CUBRID Engine
atldb_orig.h
Go to the documentation of this file.
1 // This is a part of the Active Template Library.
2 // Copyright (C) 1996-2001 Microsoft Corporation
3 // All rights reserved.
4 //
5 // This source code is only intended as a supplement to the
6 // Active Template Library Reference and related
7 // electronic documentation provided with the library.
8 // See these sources for detailed information regarding the
9 // Active Template Library product.
10 
11 #ifndef __ATLDB_H__
12 #define __ATLDB_H__
13 
14 #pragma once
15 
16 #ifndef _ATL_NO_PRAGMA_WARNINGS
17 #pragma warning (push)
18 #pragma warning(disable: 4702) // unreachable code
19 #endif // !_ATL_NO_PRAGMA_WARNINGS
20 
21 // OLE DB Provider Support
22 
23 // Interface Impl Classes
24 //
25 // Data Source Object
26 //
27 // -Mandatory Interfaces:
28 // IDBCreateSession
29 // IDBInitialize
30 // IDBProperties
31 // IPersist
32 //
33 // Session Object
34 //
35 // -Mandatory Interfaces:
36 // IGetDataSource
37 // IOpenRowset
38 // ISessionProperties
39 //
40 // -Optional Interfaces:
41 // IDBCreateCommand
42 // IDBSchemaRowset
43 //
44 // Rowset Object
45 //
46 // -Mandatory Interfaces:
47 // IAccessor
48 // IColumnsInfo
49 // IConvertType
50 // IRowset
51 // IRowsetInfo
52 //
53 // -Optional Interfaces:
54 // IRowsetIdentity
55 //
56 // Command Object
57 //
58 // -Mandatory Interfaces:
59 // ICommand)
60 // IAccessor)
61 // ICommandProperties
62 // ICommandText - derives from ICommand
63 // IColumnsInfo
64 // IConvertType
65 
66 #include <oledb.h>
67 #include <limits.h>
68 #include <oledberr.h>
69 #include <msdadc.h>
70 #include <atldbcli.h>
71 #include <atlcoll.h>
72 
73 #pragma warning(disable: 4244)
74 
75 namespace ATL
76 {
77 
78 
79 inline DBROWCOUNT AbsVal (DBROWCOUNT val)
80  {
81 
82 if (val < 0)
83 
84 return -val;
85 
86  else
87 
88 return val;
89 
90 }
91 
92 
94 // Forwards
95  template < class T > class CUtlPropInfo;
96 
97 class CColumnIds;
98 
99 
101 // Additional Property Flag needed internally
102  const int DBPROPFLAGS_CHANGE = 0x40000000;
103 
104 
106 // ATL Provider Property Definitions
107 #define ATLDB_NO_STRING 0x01000011 // Arbitrary value for AtlDumpProperty
108 
110 // ATL Provider Property Debugging Support
111 
112 inline void WINAPI AtlDumpPropsetIID (REFIID iid, DWORD dwStatus)
113  {
114 
115 USES_CONVERSION;
116 
117  // Handle the most common ones
118  TCHAR szPropertySetName[100];
119 
120 
121 if (InlineIsEqualGUID (iid, DBPROPSET_DATASOURCEALL))
122 
123  {
124 
125 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DATASOURCEALL -"));
126 
127 }
128 
129  else if (InlineIsEqualGUID (iid, DBPROPSET_DATASOURCEINFOALL))
130 
131  {
132 
133 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DATASOURCEINFOALL -"));
134 
135 }
136 
137  else if (InlineIsEqualGUID (iid, DBPROPSET_ROWSETALL))
138 
139  {
140 
141 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_ROWSETALL -"));
142 
143 }
144 
145  else if (InlineIsEqualGUID (iid, DBPROPSET_DBINITALL))
146 
147  {
148 
149 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DBINITALL -"));
150 
151 }
152 
153  else if (InlineIsEqualGUID (iid, DBPROPSET_SESSIONALL))
154 
155  {
156 
157 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_SESSIONALL -"));
158 
159 }
160 
161 if (InlineIsEqualGUID (iid, DBPROPSET_DATASOURCE))
162 
163  {
164 
165 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DATASOURCE -"));
166 
167 }
168 
169  else if (InlineIsEqualGUID (iid, DBPROPSET_DATASOURCEINFO))
170 
171  {
172 
173 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DATASOURCEINFO -"));
174 
175 }
176 
177  else if (InlineIsEqualGUID (iid, DBPROPSET_ROWSET))
178 
179  {
180 
181 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_ROWSET -"));
182 
183 }
184 
185  else if (InlineIsEqualGUID (iid, DBPROPSET_DBINIT))
186 
187  {
188 
189 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_DBINIT -"));
190 
191 }
192 
193  else if (InlineIsEqualGUID (iid, DBPROPSET_SESSION))
194 
195  {
196 
197 _tcscpy (&szPropertySetName[0], _T ("DBPROPSET_SESSION -"));
198 
199 }
200 
201  else
202 
203  {
204 
205 LPOLESTR lpszName = NULL;
206 
207 if (SUCCEEDED (StringFromCLSID (iid, &lpszName)))
208 
209 _tcscpy (&szPropertySetName[0], OLE2T (lpszName));
210 
211 }
212 
213 
214 if (dwStatus & 0x04 /* GETPROP_ERRORSOCCURRED */ )
215 
216 _tcscat (szPropertySetName, _T (" NOT FOUND\n"));
217 
218  else
219 
220 _tcscat (szPropertySetName, _T (" FOUND\n"));
221 
222 
223 OutputDebugString (szPropertySetName);
224 
225 }
226 
227 
228 
229 inline void WINAPI AtlDumpProperty (DWORD dwPropertyID, DWORD dwStatus)
230  {
231 
232 TCHAR szProperty[100];
233 
234 TCHAR szStatus[24];
235 
236 
237 switch (dwStatus)
238 
239  {
240 
241 case DBPROPSTATUS_OK:
242 
243 _tcscpy (&szStatus[0], _T ("FOUND"));
244 
245 break;
246 
247 case DBPROPSTATUS_NOTSUPPORTED:
248 
249 _tcscpy (&szStatus[0], _T ("NOT SUPPORTED"));
250 
251 break;
252 
253 case DBPROPSTATUS_BADVALUE:
254 
255 _tcscpy (&szStatus[0], _T ("BAD VALUE"));
256 
257 break;
258 
259 case DBPROPSTATUS_BADOPTION:
260 
261 _tcscpy (&szStatus[0], _T ("BAD OPTION"));
262 
263 break;
264 
265 case DBPROPSTATUS_BADCOLUMN:
266 
267 _tcscpy (&szStatus[0], _T ("BAD COLUMN"));
268 
269 break;
270 
271 case DBPROPSTATUS_NOTALLSETTABLE:
272 
273 _tcscpy (&szStatus[0], _T ("NOT ALL SETTABLE"));
274 
275 break;
276 
277 case DBPROPSTATUS_NOTSETTABLE:
278 
279 _tcscpy (&szStatus[0], _T ("NOT SETTABLE"));
280 
281 break;
282 
283 case DBPROPSTATUS_NOTSET:
284 
285 _tcscpy (&szStatus[0], _T ("NOT SET"));
286 
287 break;
288 
289 case DBPROPSTATUS_CONFLICTING:
290 
291 _tcscpy (&szStatus[0], _T ("CONFLICTED"));
292 
293 break;
294 
295 case ATLDB_NO_STRING:
296 
297 _tcscpy (&szStatus[0], _T ("WARNING! NO RESOURCE STRING FOR THIS PROPERTY! ADD IDS_<PROP_NAME>"));
298 
299 break;
300 
301 default:
302 
303 _tcscpy (&szStatus[0], _T ("INDETERMINATE"));
304 
305 break;
306 
307 }
308 
309 
310 wsprintf (&szProperty[0], _T ("Property 0x%lxL -- %s\n"), dwPropertyID, szStatus);
311 
312 OutputDebugString (szProperty);
313 
314 }
315 
316 
317 
319 // Defines for debugging properties
320 
321 #ifdef _ATL_DEBUG_PROVIDER_PROPS
322 #define _ATLDUMPPROPSETIID(iid, dwStatus) AtlDumpPropsetIID(iid, dwStatus)
323 #define _ATLDUMPPROPERTY(dwPropertyID, dwStatus) AtlDumpProperty(dwPropertyID, dwStatus)
324 #else /*
325  */
326 #define _ATLDUMPPROPSETIID(iid, dwStatus)
327 #define _ATLDUMPPROPERTY(dwPropertyID, dwStatus)
328 #endif // _ATL_DEBUG_PROVIDER_PROPS
329 
330 // ------------- STRUCTURE DEFINITIONS -----------------------------------
331 
332 struct UPROPVAL
333  {
334 
335 DBPROPOPTIONS dwOption;
336 
338 
339 DWORD dwFlags;
340 
341 VARIANT vValue;
342 
343 };
344 
345 
346 struct UPROPINFO
347  {
348 
349 DBPROPID dwPropId;
350 
351 ULONG ulIDS;
352 
353 VARTYPE VarType;
354 
355 DBPROPFLAGS dwFlags;
356 
357 union
358  {
359 
360 DWORD_PTR dwVal;
361 
362 LPOLESTR szVal;
363 
364 };
365 
366 DBPROPOPTIONS dwOption;
367 
368 };
369 
370 
371 struct UPROP
372  {
373 
374 ULONG cPropIds;
375 
376 UPROPINFO ** rgpUPropInfo;
377 
378 UPROPVAL * pUPropVal;
379 
380 };
381 
382 
383 struct PROPCOLID
384  {
385 
386 DBID dbidProperty; // The column id information
387  DBPROPOPTIONS dwOption;
388 
389 VARIANT vValue;
390 
391 };
392 
393 
394 typedef PROPCOLID *PPROPCOLID;
395 
396 
397 struct UPROPSET
398  {
399 
400 const GUID *pPropSet;
401 
402 ULONG cUPropInfo;
403 
404 UPROPINFO * pUPropInfo;
405 
406 DWORD dwFlags;
407 
408 bool bIsChained;
409 
410 };
411 
412 
413 struct ATLBINDINGS
414  {
415 
416 DBBINDING * pBindings;
417 
418 DWORD dwRef; // DBREFCOUNT dwRef;
419  DBCOUNTITEM cBindings;
420 
421 DBACCESSORFLAGS dwAccessorFlags;
422 
423 };
424 
425 
426 struct ATLCOLUMNINFO
427  {
428 
429 LPOLESTR pwszName;
430 
431 ITypeInfo * pTypeInfo;
432 
433 DBORDINAL iOrdinal;
434 
435 DBCOLUMNFLAGS dwFlags;
436 
437 DBLENGTH ulColumnSize;
438 
439 DBTYPE wType;
440 
441 BYTE bPrecision;
442 
443 BYTE bScale;
444 
445 DBID columnid;
446 
447 DBBYTEOFFSET cbOffset;
448 
449 };
450 
451 
452 //
453 // The following very large sections of defines are to implement auto determination
454 // of Property map constants based on a stringized prop name. There is one set for
455 // Type (VT_), one for Init Value, and one for Property flags.
456 //
457 
458 #define ABORTPRESERVE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
459 #define ACTIVESESSIONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
460 #define APPENDONLY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
461 #define ASYNCTXNABORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
462 #define ASYNCTXNCOMMIT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
463 #define AUTH_CACHE_AUTHINFO_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
464 #define AUTH_ENCRYPT_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
465 #define AUTH_INTEGRATED_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
466 #define AUTH_MASK_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
467 #define AUTH_PASSWORD_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
468 #define AUTH_PERSIST_ENCRYPTED_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
469 #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
470 #define AUTH_USERID_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
471 #define BLOCKINGSTORAGEOBJECTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
472 #define BOOKMARKS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
473 #define BOOKMARKSKIPPED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
474 #define BOOKMARKTYPE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
475 #define BYREFACCESSORS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
476 #define CACHEDEFERRED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
477 #define CANFETCHBACKWARDS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
478 #define CANHOLDROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
479 #define CANSCROLLBACKWARDS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
480 #define CATALOGLOCATION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
481 #define CATALOGTERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
482 #define CATALOGUSAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
483 #define CHANGEINSERTEDROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_CHANGE )
484 #define COL_AUTOINCREMENT_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
485 #define COL_DEFAULT_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
486 #define COL_DESCRIPTION_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
487 #define COL_FIXEDLENGTH_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
488 #define COL_NULLABLE_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
489 #define COL_PRIMARYKEY_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
490 #define COL_UNIQUE_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
491 #define COLUMNDEFINITION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
492 #define COLUMNRESTRICT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
493 #define COMMANDTIMEOUT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
494 #define COMMITPRESERVE_Flags ( DBPROPFLAGS_ROWSET| DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
495 #define CONCATNULLBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
496 #define CURRENTCATALOG_Flags ( DBPROPFLAGS_DATASOURCE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
497 #define DATASOURCENAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
498 #define DATASOURCEREADONLY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
499 #define DBMSNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
500 #define DBMSVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
501 #define DEFERRED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
502 #define DELAYSTORAGEOBJECTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
503 #define DSOTHREADMODEL_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
504 #define GROUPBY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
505 #define HETEROGENEOUSTABLES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
506 #define IAccessor_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
507 #define IColumnsInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
508 #define IColumnsRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
509 #define IConnectionPointContainer_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
510 #define IConvertType_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
511 #define IRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
512 #define IRowsetChange_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
513 #define IRowsetIdentity_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
514 #define IRowsetIndex_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
515 #define IRowsetInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
516 #define IRowsetLocate_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
517 #define IRowsetResynch_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
518 #define IRowsetScroll_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
519 #define IRowsetUpdate_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
520 #define ISupportErrorInfo_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
521 #define ILockBytes_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
522 #define ISequentialStream_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
523 #define IStorage_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
524 #define IStream_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
525 #define IDENTIFIERCASE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
526 #define IMMOBILEROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
527 #define INDEX_AUTOUPDATE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
528 #define INDEX_CLUSTERED_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
529 #define INDEX_FILLFACTOR_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
530 #define INDEX_INITIALSIZE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
531 #define INDEX_NULLCOLLATION_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
532 #define INDEX_NULLS_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
533 #define INDEX_PRIMARYKEY_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
534 #define INDEX_SORTBOOKMARKS_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
535 #define INDEX_TEMPINDEX_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
536 #define INDEX_TYPE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
537 #define INDEX_UNIQUE_Flags ( DBPROPFLAGS_INDEX | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
538 #define INIT_DATASOURCE_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
539 #define INIT_HWND_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
540 #define INIT_IMPERSONATION_LEVEL_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
541 #define INIT_LCID_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
542 #define INIT_LOCATION_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
543 #define INIT_MODE_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
544 #define INIT_PROMPT_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
545 #define INIT_PROTECTION_LEVEL_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
546 #define INIT_PROVIDERSTRING_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
547 #define INIT_TIMEOUT_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
548 #define LITERALBOOKMARKS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
549 #define LITERALIDENTITY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
550 #define MAXINDEXSIZE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
551 #define MAXOPENROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
552 #define MAXPENDINGROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
553 #define MAXROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
554 #define MAXROWSIZE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
555 #define MAXROWSIZEINCLUDESBLOB_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
556 #define MAXTABLESINSELECT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
557 #define MAYWRITECOLUMN_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
558 #define MEMORYUSAGE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
559 #define MULTIPLEPARAMSETS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
560 #define MULTIPLERESULTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
561 #define MULTIPLESTORAGEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
562 #define MULTITABLEUPDATE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
563 #define NOTIFICATIONGRANULARITY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
564 #define NOTIFICATIONPHASES_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
565 #define NOTIFYCOLUMNSET_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
566 #define NOTIFYROWDELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
567 #define NOTIFYROWFIRSTCHANGE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
568 #define NOTIFYROWINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
569 #define NOTIFYROWRESYNCH_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
570 #define NOTIFYROWSETRELEASE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
571 #define NOTIFYROWSETFETCHPOSITIONCHANGE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
572 #define NOTIFYROWUNDOCHANGE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
573 #define NOTIFYROWUNDODELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
574 #define NOTIFYROWUNDOINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
575 #define NOTIFYROWUPDATE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
576 #define NULLCOLLATION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
577 #define OLEOBJECTS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
578 #define ORDERBYCOLUMNSINSELECT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
579 #define ORDEREDBOOKMARKS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
580 #define OTHERINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
581 #define OTHERUPDATEDELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
582 #define OUTPUTPARAMETERAVAILABILITY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
583 #define OWNINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
584 #define OWNUPDATEDELETE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
585 #define PERSISTENTIDTYPE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
586 #define PREPAREABORTBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
587 #define PREPARECOMMITBEHAVIOR_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
588 #define PROCEDURETERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
589 #define PROVIDERNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
590 #define PROVIDEROLEDBVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
591 #define PROVIDERVER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
592 #define QUICKRESTART_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
593 #define QUOTEDIDENTIFIERCASE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
594 #define REENTRANTEVENTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
595 #define REMOVEDELETED_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
596 #define REPORTMULTIPLECHANGES_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_CHANGE )
597 #define RETURNPENDINGINSERTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
598 #define ROWRESTRICT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
599 #define ROWSETCONVERSIONSONCOMMAND_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
600 #define ROWTHREADMODEL_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
601 #define SCHEMATERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
602 #define SCHEMAUSAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
603 #define SERVERCURSOR_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
604 #define SESS_AUTOCOMMITISOLEVELS_Flags ( DBPROPFLAGS_SESSION | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE)
605 #define SQLSUPPORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
606 #define STRONGIDENTITY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
607 #define STRUCTUREDSTORAGE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
608 #define SUBQUERIES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
609 #define SUPPORTEDTXNDDL_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
610 #define SUPPORTEDTXNISOLEVELS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
611 #define SUPPORTEDTXNISORETAIN_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
612 #define TABLETERM_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
613 #define TBL_TEMPTABLE_Flags ( DBPROPFLAGS_TABLE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
614 #define TRANSACTEDOBJECT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
615 #define UPDATABILITY_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
616 #define USERNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
617 // 1.5
618 #define FILTERCOMPAREOPS_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ )
619 #define FINDCOMPAREOPS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
620 #define IChapteredRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
621 #define IDBAsynchStatus_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
622 #define IRowsetFind_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
623 #define IRowsetView_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
624 #define IViewChapter_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
625 #define IViewFilter_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
626 #define IViewRowset_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
627 #define IViewSort_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
628 #define INIT_ASYNCH_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
629 #define MAXOPENCHAPTERS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
630 #define MAXORSINFILTER_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ )
631 #define MAXSORTCOLUMNS_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ )
632 #define ROWSET_ASYNCH_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
633 #define SORTONINDEX_Flags ( DBPROPFLAGS_VIEW | DBPROPFLAGS_READ )
634 // 2.0
635 #define IMultipleResults_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
636 #define DATASOURCE_TYPE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
637 //MDPROP
638 #define AXES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
639 #define FLATTENING_SUPPORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
640 #define MDX_JOINCUBES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
641 #define NAMED_LEVELS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
642 //#define RANGEROWSET_Flags ( )
643 #define MDX_SLICER_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
644 //#define MDX_CUBEQUALIFICATION_Flags ( )
645 #define MDX_OUTERREFERENCE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
646 #define MDX_QUERYBYPROPERTY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
647 #define MDX_CASESUPPORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
648 #define MDX_STRING_COMPOP_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
649 #define MDX_DESCFLAGS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
650 #define MDX_SET_FUNCTIONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
651 #define MDX_MEMBER_FUNCTIONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
652 #define MDX_NUMERIC_FUNCTIONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
653 #define MDX_FORMULAS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
654 #define AGGREGATECELL_UPDATE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
655 //#define MDX_AGGREGATECELL_UPDATE_Flags ( )
656 #define MDX_OBJQUALIFICATION_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
657 #define MDX_NONMEASURE_EXPRESSONS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
658 // DBPROP
659 #define ACCESSORDER_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
660 #define BOOKMARKINFO_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
661 #define INIT_CATALOG_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
662 #define ROW_BULKOPS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE ) // !!!
663 #define PROVIDERFRIENDLYNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
664 #define LOCKMODE_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
665 #define MULTIPLECONNECTIONS_Flags ( DBPROPFLAGS_DATASOURCE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
666 #define UNIQUEROWS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
667 #define SERVERDATAONINSERT_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
668 //#define STORAGEFLAGS_Flags ( )
669 #define CONNECTIONSTATUS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
670 #define ALTERCOLUMN_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
671 #define COLUMNLCID_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ )
672 #define RESETDATASOURCE_Flags ( DBPROPFLAGS_DATASOURCE | DBPROPFLAGS_WRITE )
673 #define INIT_OLEDBSERVICES_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
674 #define IRowsetRefresh_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
675 #define SERVERNAME_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
676 #define IParentRowset_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
677 #define HIDDENCOLUMNS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ )
678 #define PROVIDERMEMORY_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
679 #define CLIENTCURSOR_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
680 // 2.1
681 #define TRUSTEE_USERNAME_Flags ( DBPROPFLAGS_TRUSTEE | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
682 #define TRUSTEE_AUTHENTICATION_Flags ( DBPROPFLAGS_TRUSTEE | DBPROPFLAGS_WRITE )
683 #define TRUSTEE_NEWAUTHENTICATION_Flags ( DBPROPFLAGS_TRUSTEE | DBPROPFLAGS_WRITE )
684 #define IRow_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
685 #define IRowChange_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
686 #define IRowSchemaChange_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
687 #define IGetRow_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
688 #define IScopedOperations_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
689 #define IBindResource_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
690 #define ICreateRow_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
691 #define INIT_BINDFLAGS_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
692 #define INIT_LOCKOWNER_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
693 #define GENERATEURL_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
694 //#define IDBBinderProperties_Flags ( )
695 #define IColumnsInfo2_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
696 //#define IRegisterProvider_Flags ( )
697 #define IGetSession_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
698 #define IGetSourceRow_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
699 #define IRowsetCurrentIndex_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
700 #define OPENROWSETSUPPORT_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
701 #define COL_ISLONG_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
702 // 2.5
703 #define COL_SEED_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
704 #define COL_INCREMENT_Flags ( DBPROPFLAGS_COLUMN | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
705 #define INIT_GENERALTIMEOUT_Flags ( DBPROPFLAGS_DBINIT | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
706 #define COMSERVICES_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
707 // 2.6
708 #define OUTPUTSTREAM_Flags ( DBPROPFLAGS_STREAM | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
709 #define OUTPUTENCODING_Flags ( DBPROPFLAGS_STREAM | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
710 #define TABLESTATISTICS_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ )
711 #define SKIPROWCOUNTRESULTS_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
712 #define IRowsetBookmark_Flags ( DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE )
713 #define VISUALMODE_Flags ( DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_WRITE )
714 
715 
716 #define ABORTPRESERVE_Type VT_BOOL
717 #define ACTIVESESSIONS_Type VT_I4
718 #define APPENDONLY_Type VT_BOOL
719 #define ASYNCTXNABORT_Type VT_BOOL
720 #define ASYNCTXNCOMMIT_Type VT_BOOL
721 #define AUTH_CACHE_AUTHINFO_Type VT_BOOL
722 #define AUTH_ENCRYPT_PASSWORD_Type VT_BOOL
723 #define AUTH_INTEGRATED_Type VT_BSTR
724 #define AUTH_MASK_PASSWORD_Type VT_BOOL
725 #define AUTH_PASSWORD_Type VT_BSTR
726 #define AUTH_PERSIST_ENCRYPTED_Type VT_BOOL
727 #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Type VT_BOOL
728 #define AUTH_USERID_Type VT_BSTR
729 #define BLOCKINGSTORAGEOBJECTS_Type VT_BOOL
730 #define BOOKMARKS_Type VT_BOOL
731 #define BOOKMARKSKIPPED_Type VT_BOOL
732 #define BOOKMARKTYPE_Type VT_I4
733 #define BYREFACCESSORS_Type VT_BOOL
734 #define CACHEDEFERRED_Type VT_BOOL
735 #define CANFETCHBACKWARDS_Type VT_BOOL
736 #define CANHOLDROWS_Type VT_BOOL
737 #define CANSCROLLBACKWARDS_Type VT_BOOL
738 #define CATALOGLOCATION_Type VT_I4
739 #define CATALOGTERM_Type VT_BSTR
740 #define CATALOGUSAGE_Type VT_I4
741 #define CHANGEINSERTEDROWS_Type VT_BOOL
742 #define COL_AUTOINCREMENT_Type VT_BOOL
743 #define COL_DEFAULT_Type VT_BSTR
744 #define COL_DESCRIPTION_Type VT_BSTR
745 #define COL_FIXEDLENGTH_Type VT_BOOL
746 #define COL_NULLABLE_Type VT_BOOL
747 #define COL_PRIMARYKEY_Type VT_BOOL
748 #define COL_UNIQUE_Type VT_BOOL
749 #define COLUMNDEFINITION_Type VT_I4
750 #define COLUMNRESTRICT_Type VT_BOOL
751 #define COMMANDTIMEOUT_Type VT_I4
752 #define COMMITPRESERVE_Type VT_BOOL
753 #define CONCATNULLBEHAVIOR_Type VT_I4
754 #define CURRENTCATALOG_Type VT_BSTR
755 #define DATASOURCENAME_Type VT_BSTR
756 #define DATASOURCEREADONLY_Type VT_BOOL
757 #define DBMSNAME_Type VT_BSTR
758 #define DBMSVER_Type VT_BSTR
759 #define DEFERRED_Type VT_BOOL
760 #define DELAYSTORAGEOBJECTS_Type VT_BOOL
761 #define DSOTHREADMODEL_Type VT_I4
762 #define GROUPBY_Type VT_I4
763 #define HETEROGENEOUSTABLES_Type VT_I4
764 #define IAccessor_Type VT_BOOL
765 #define IColumnsInfo_Type VT_BOOL
766 #define IColumnsRowset_Type VT_BOOL
767 #define IConnectionPointContainer_Type VT_BOOL
768 #define IConvertType_Type VT_BOOL
769 #define IRowset_Type VT_BOOL
770 #define IRowsetChange_Type VT_BOOL
771 #define IRowsetIdentity_Type VT_BOOL
772 #define IRowsetIndex_Type VT_BOOL
773 #define IRowsetInfo_Type VT_BOOL
774 #define IRowsetLocate_Type VT_BOOL
775 #define IRowsetResynch_Type VT_BOOL
776 #define IRowsetScroll_Type VT_BOOL
777 #define IRowsetUpdate_Type VT_BOOL
778 #define ISupportErrorInfo_Type VT_BOOL
779 #define ILockBytes_Type VT_BOOL
780 #define ISequentialStream_Type VT_BOOL
781 #define IStorage_Type VT_BOOL
782 #define IStream_Type VT_BOOL
783 #define IDENTIFIERCASE_Type VT_I4
784 #define IMMOBILEROWS_Type VT_BOOL
785 #define INDEX_AUTOUPDATE_Type VT_BOOL
786 #define INDEX_CLUSTERED_Type VT_BOOL
787 #define INDEX_FILLFACTOR_Type VT_I4
788 #define INDEX_INITIALSIZE_Type VT_I4
789 #define INDEX_NULLCOLLATION_Type VT_I4
790 #define INDEX_NULLS_Type VT_I4
791 #define INDEX_PRIMARYKEY_Type VT_BOOL
792 #define INDEX_SORTBOOKMARKS_Type VT_BOOL
793 #define INDEX_TEMPINDEX_Type VT_BOOL
794 #define INDEX_TYPE_Type VT_I4
795 #define INDEX_UNIQUE_Type VT_BOOL
796 #define INIT_DATASOURCE_Type VT_BSTR
797 #define INIT_HWND_Type VT_I4
798 #define INIT_IMPERSONATION_LEVEL_Type VT_I4
799 #define INIT_LCID_Type VT_I4
800 #define INIT_LOCATION_Type VT_BSTR
801 #define INIT_MODE_Type VT_I4
802 #define INIT_PROMPT_Type VT_I2
803 #define INIT_PROTECTION_LEVEL_Type VT_I4
804 #define INIT_PROVIDERSTRING_Type VT_BSTR
805 #define INIT_TIMEOUT_Type VT_I4
806 #define LITERALBOOKMARKS_Type VT_BOOL
807 #define LITERALIDENTITY_Type VT_BOOL
808 #define MAXINDEXSIZE_Type VT_I4
809 #define MAXOPENROWS_Type VT_I4
810 #define MAXPENDINGROWS_Type VT_I4
811 #define MAXROWS_Type VT_I4
812 #define MAXROWSIZE_Type VT_I4
813 #define MAXROWSIZEINCLUDESBLOB_Type VT_BOOL
814 #define MAXTABLESINSELECT_Type VT_I4
815 #define MAYWRITECOLUMN_Type VT_BOOL
816 #define MEMORYUSAGE_Type VT_I4
817 #define MULTIPLEPARAMSETS_Type VT_BOOL
818 #define MULTIPLERESULTS_Type VT_I4
819 #define MULTIPLESTORAGEOBJECTS_Type VT_BOOL
820 #define MULTITABLEUPDATE_Type VT_BOOL
821 #define NOTIFICATIONGRANULARITY_Type VT_I4
822 #define NOTIFICATIONPHASES_Type VT_I4
823 #define NOTIFYCOLUMNSET_Type VT_I4
824 #define NOTIFYROWDELETE_Type VT_I4
825 #define NOTIFYROWFIRSTCHANGE_Type VT_I4
826 #define NOTIFYROWINSERT_Type VT_I4
827 #define NOTIFYROWRESYNCH_Type VT_I4
828 #define NOTIFYROWSETRELEASE_Type VT_I4
829 #define NOTIFYROWSETFETCHPOSITIONCHANGE_Type VT_I4
830 #define NOTIFYROWUNDOCHANGE_Type VT_I4
831 #define NOTIFYROWUNDODELETE_Type VT_I4
832 #define NOTIFYROWUNDOINSERT_Type VT_I4
833 #define NOTIFYROWUPDATE_Type VT_I4
834 #define NULLCOLLATION_Type VT_I4
835 #define OLEOBJECTS_Type VT_I4
836 #define ORDERBYCOLUMNSINSELECT_Type VT_BOOL
837 #define ORDEREDBOOKMARKS_Type VT_BOOL
838 #define OTHERINSERT_Type VT_BOOL
839 #define OTHERUPDATEDELETE_Type VT_BOOL
840 #define OUTPUTPARAMETERAVAILABILITY_Type VT_I4
841 #define OWNINSERT_Type VT_BOOL
842 #define OWNUPDATEDELETE_Type VT_BOOL
843 #define PERSISTENTIDTYPE_Type VT_I4
844 #define PREPAREABORTBEHAVIOR_Type VT_I4
845 #define PREPARECOMMITBEHAVIOR_Type VT_I4
846 #define PROCEDURETERM_Type VT_BSTR
847 #define PROVIDERNAME_Type VT_BSTR
848 #define PROVIDEROLEDBVER_Type VT_BSTR
849 #define PROVIDERVER_Type VT_BSTR
850 #define QUICKRESTART_Type VT_BOOL
851 #define QUOTEDIDENTIFIERCASE_Type VT_I4
852 #define REENTRANTEVENTS_Type VT_BOOL
853 #define REMOVEDELETED_Type VT_BOOL
854 #define REPORTMULTIPLECHANGES_Type VT_BOOL
855 #define RETURNPENDINGINSERTS_Type VT_BOOL
856 #define ROWRESTRICT_Type VT_BOOL
857 #define ROWSETCONVERSIONSONCOMMAND_Type VT_BOOL
858 #define ROWTHREADMODEL_Type VT_I4
859 #define SCHEMATERM_Type VT_BSTR
860 #define SCHEMAUSAGE_Type VT_I4
861 #define SERVERCURSOR_Type VT_BOOL
862 #define SESS_AUTOCOMMITISOLEVELS_Type VT_I4
863 #define SQLSUPPORT_Type VT_I4
864 #define STRONGIDENTITY_Type VT_BOOL
865 #define STRUCTUREDSTORAGE_Type VT_I4
866 #define SUBQUERIES_Type VT_I4
867 #define SUPPORTEDTXNDDL_Type VT_I4
868 #define SUPPORTEDTXNISOLEVELS_Type VT_I4
869 #define SUPPORTEDTXNISORETAIN_Type VT_I4
870 #define TABLETERM_Type VT_BSTR
871 #define TBL_TEMPTABLE_Type VT_BOOL
872 #define TRANSACTEDOBJECT_Type VT_BOOL
873 #define UPDATABILITY_Type VT_I4
874 #define USERNAME_Type VT_BSTR
875 // 1.5
876 #define FILTERCOMPAREOPS_Type VT_I4
877 #define FINDCOMPAREOPS_Type VT_I4
878 #define IChapteredRowset_Type VT_BOOL
879 #define IDBAsynchStatus_Type VT_BOOL
880 #define IRowsetFind_Type VT_BOOL
881 #define IRowsetView_Type VT_BOOL
882 #define IViewChapter_Type VT_BOOL
883 #define IViewFilter_Type VT_BOOL
884 #define IViewRowset_Type VT_BOOL
885 #define IViewSort_Type VT_BOOL
886 #define INIT_ASYNCH_Type VT_I4
887 #define MAXOPENCHAPTERS_Type VT_I4
888 #define MAXORSINFILTER_Type VT_I4
889 #define MAXSORTCOLUMNS_Type VT_I4
890 #define ROWSET_ASYNCH_Type VT_I4
891 #define SORTONINDEX_Type VT_BOOL
892 // 2.0
893 #define IMultipleResults_Flags_Type VT_BOOL
894 #define DATASOURCE_TYPE_Flags_Type VT_I4
895 //MDPROP
896 #define AXES_Type VT_I4
897 #define FLATTENING_SUPPORT_Type VT_I4
898 #define MDX_JOINCUBES_Type VT_I4
899 #define NAMED_LEVELS_Type VT_I4
900 //#define RANGEROWSET_Type
901 #define MDX_SLICER_Type VT_I4
902 //#define MDX_CUBEQUALIFICATION_Type
903 #define MDX_OUTERREFERENCE_Type VT_I4
904 #define MDX_QUERYBYPROPERTY_Type VT_BOOL
905 #define MDX_CASESUPPORT_Type VT_I4
906 #define MDX_STRING_COMPOP_Type VT_I4
907 #define MDX_DESCFLAGS_Type VT_I4
908 #define MDX_SET_FUNCTIONS_Type VT_I4
909 #define MDX_MEMBER_FUNCTIONS_Type VT_I4
910 #define MDX_NUMERIC_FUNCTIONS_Type VT_I4
911 #define MDX_FORMULAS_Type VT_I4
912 #define AGGREGATECELL_UPDATE_Type VT_I4
913 //#define MDX_AGGREGATECELL_UPDATE_Type
914 #define MDX_OBJQUALIFICATION_Type VT_I4
915 #define MDX_NONMEASURE_EXPRESSONS_Type VT_I4
916 // DBPROP
917 #define ACCESSORDER_Type VT_I4
918 #define BOOKMARKINFO_Type VT_I4
919 #define INIT_CATALOG_Type VT_BSTR
920 #define ROW_BULKOPS_Type VT_I4
921 #define PROVIDERFRIENDLYNAME_Type VT_BSTR
922 #define LOCKMODE_Type VT_I4
923 #define MULTIPLECONNECTIONS_Type VT_BOOL
924 #define UNIQUEROWS_Type VT_BOOL
925 #define SERVERDATAONINSERT_Type VT_BOOL
926 //#define STORAGEFLAGS_Type
927 #define CONNECTIONSTATUS_Type VT_I4
928 #define ALTERCOLUMN_Type VT_I4
929 #define COLUMNLCID_Type VT_I4
930 #define RESETDATASOURCE_Type VT_I4
931 #define INIT_OLEDBSERVICES_Type VT_I4
932 #define IRowsetRefresh_Type VT_BOOL
933 #define SERVERNAME_Type VT_BSTR
934 #define IParentRowset_Type VT_BOOL
935 #define HIDDENCOLUMNS_Type VT_I4
936 #define PROVIDERMEMORY_Type VT_BOOL
937 #define CLIENTCURSOR_Type VT_BOOL
938 // 2.1
939 #define TRUSTEE_USERNAME_Type VT_BSTR
940 #define TRUSTEE_AUTHENTICATION_Type VT_BSTR
941 #define TRUSTEE_NEWAUTHENTICATION_Type VT_BSTR
942 #define IRow_Type VT_BOOL
943 #define IRowChange_Type VT_BOOL
944 #define IRowSchemaChange_Type VT_BOOL
945 #define IGetRow_Type VT_BOOL
946 #define IScopedOperations_Type VT_BOOL
947 #define IBindResource_Type VT_BOOL
948 #define ICreateRow_Type VT_BOOL
949 #define INIT_BINDFLAGS_Type VT_I4
950 #define INIT_LOCKOWNER_Type VT_BSTR
951 #define GENERATEURL_Type VT_I4
952 //#define IDBBinderProperties_Type
953 #define IColumnsInfo2_Type VT_BOOL
954 //#define IRegisterProvider_Type
955 #define IGetSession_Type VT_BOOL
956 #define IGetSourceRow_Type VT_BOOL
957 #define IRowsetCurrentIndex_Type VT_BOOL
958 #define OPENROWSETSUPPORT_Type VT_I4
959 #define COL_ISLONG_Type VT_BOOL
960 // 2.5
961 //#define COL_SEED_Type VT_VARIANT //!!!
962 //#define COL_INCREMENT_Type VT_VARIANT //!!!
963 #define INIT_GENERALTIMEOUT_Type VT_I4
964 #define COMSERVICES_Type VT_I4
965 // 2.6
966 #define OUTPUTSTREAM_Type VT_UNKNOWN
967 #define OUTPUTENCODING_Type VT_BSTR
968 #define TABLESTATISTICS_Type VT_I4
969 #define SKIPROWCOUNTRESULTS_Type VT_BOOL
970 #define IRowsetBookmark_Type VT_BOOL
971 #define VISUALMODE_Type VT_I4
972 
973 
974 
975 #define ABORTPRESERVE_Value ATL_VARIANT_FALSE
976 #define ACTIVESESSIONS_Value 0
977 #define APPENDONLY_Value ATL_VARIANT_FALSE
978 #define ASYNCTXNABORT_Value ATL_VARIANT_FALSE
979 #define ASYNCTXNCOMMIT_Value ATL_VARIANT_FALSE
980 #define AUTH_CACHE_AUTHINFO_Value ATL_VARIANT_FALSE
981 #define AUTH_ENCRYPT_PASSWORD_Value ATL_VARIANT_FALSE
982 #define AUTH_INTEGRATED_Value OLESTR("")
983 #define AUTH_MASK_PASSWORD_Value ATL_VARIANT_FALSE
984 #define AUTH_PASSWORD_Value OLESTR("")
985 #define AUTH_PERSIST_ENCRYPTED_Value ATL_VARIANT_FALSE
986 #define AUTH_PERSIST_SENSITIVE_AUTHINFO_Value ATL_VARIANT_FALSE
987 #define AUTH_USERID_Value OLESTR("")
988 #define BLOCKINGSTORAGEOBJECTS_Value ATL_VARIANT_FALSE
989 #define BOOKMARKS_Value ATL_VARIANT_FALSE
990 #define BOOKMARKSKIPPED_Value ATL_VARIANT_FALSE
991 #define BOOKMARKTYPE_Value 0
992 #define BYREFACCESSORS_Value ATL_VARIANT_FALSE
993 #define CACHEDEFERRED_Value ATL_VARIANT_FALSE
994 #define CANFETCHBACKWARDS_Value ATL_VARIANT_TRUE
995 #define CANHOLDROWS_Value ATL_VARIANT_TRUE
996 #define CANSCROLLBACKWARDS_Value ATL_VARIANT_TRUE
997 #define CATALOGLOCATION_Value 0
998 #define CATALOGTERM_Value OLESTR("")
999 #define CATALOGUSAGE_Value 0
1000 #define CHANGEINSERTEDROWS_Value ATL_VARIANT_FALSE
1001 #define COL_AUTOINCREMENT_Value ATL_VARIANT_FALSE
1002 #define COL_DEFAULT_Value OLESTR("")
1003 #define COL_DESCRIPTION_Value OLESTR("")
1004 #define COL_FIXEDLENGTH_Value ATL_VARIANT_FALSE
1005 #define COL_NULLABLE_Value ATL_VARIANT_FALSE
1006 #define COL_PRIMARYKEY_Value ATL_VARIANT_FALSE
1007 #define COL_UNIQUE_Value ATL_VARIANT_FALSE
1008 #define COLUMNDEFINITION_Value 0
1009 #define COLUMNRESTRICT_Value ATL_VARIANT_FALSE
1010 #define COMMANDTIMEOUT_Value 0
1011 #define COMMITPRESERVE_Value ATL_VARIANT_FALSE
1012 #define CONCATNULLBEHAVIOR_Value 0
1013 #define CURRENTCATALOG_Value OLESTR("")
1014 #define DATASOURCENAME_Value OLESTR("")
1015 #define DATASOURCEREADONLY_Value ATL_VARIANT_TRUE
1016 #define DBMSNAME_Value OLESTR("")
1017 #define DBMSVER_Value OLESTR("")
1018 #define DEFERRED_Value ATL_VARIANT_FALSE
1019 #define DELAYSTORAGEOBJECTS_Value ATL_VARIANT_FALSE
1020 #define DSOTHREADMODEL_Value DBPROPVAL_RT_APTMTTHREAD
1021 #define GROUPBY_Value 0
1022 #define HETEROGENEOUSTABLES_Value 0
1023 #define IAccessor_Value ATL_VARIANT_TRUE
1024 #define IColumnsInfo_Value ATL_VARIANT_TRUE
1025 #define IColumnsRowset_Value ATL_VARIANT_FALSE
1026 #define IConnectionPointContainer_Value ATL_VARIANT_FALSE
1027 #define IConvertType_Value ATL_VARIANT_TRUE
1028 #define IRowset_Value ATL_VARIANT_TRUE
1029 #define IRowsetChange_Value ATL_VARIANT_FALSE
1030 #define IRowsetIdentity_Value ATL_VARIANT_TRUE
1031 #define IRowsetIndex_Value ATL_VARIANT_FALSE
1032 #define IRowsetInfo_Value ATL_VARIANT_TRUE
1033 #define IRowsetLocate_Value ATL_VARIANT_FALSE
1034 #define IRowsetResynch_Value ATL_VARIANT_FALSE
1035 #define IRowsetScroll_Value ATL_VARIANT_FALSE
1036 #define IRowsetUpdate_Value ATL_VARIANT_FALSE
1037 #define ISupportErrorInfo_Value ATL_VARIANT_FALSE
1038 #define ILockBytes_Value ATL_VARIANT_FALSE
1039 #define ISequentialStream_Value ATL_VARIANT_FALSE
1040 #define IStorage_Value ATL_VARIANT_FALSE
1041 #define IStream_Value ATL_VARIANT_FALSE
1042 #define IDENTIFIERCASE_Value 0
1043 #define IMMOBILEROWS_Value ATL_VARIANT_FALSE
1044 #define INDEX_AUTOUPDATE_Value ATL_VARIANT_FALSE
1045 #define INDEX_CLUSTERED_Value ATL_VARIANT_FALSE
1046 #define INDEX_FILLFACTOR_Value 0
1047 #define INDEX_INITIALSIZE_Value 0
1048 #define INDEX_NULLCOLLATION_Value 0
1049 #define INDEX_NULLS_Value 0
1050 #define INDEX_PRIMARYKEY_Value ATL_VARIANT_FALSE
1051 #define INDEX_SORTBOOKMARKS_Value ATL_VARIANT_FALSE
1052 #define INDEX_TEMPINDEX_Value ATL_VARIANT_FALSE
1053 #define INDEX_TYPE_Value 0
1054 #define INDEX_UNIQUE_Value ATL_VARIANT_FALSE
1055 #define INIT_DATASOURCE_Value OLESTR("")
1056 #define INIT_HWND_Value 0
1057 #define INIT_IMPERSONATION_LEVEL_Value 0
1058 #define INIT_LCID_Value 0
1059 #define INIT_LOCATION_Value OLESTR("")
1060 #define INIT_MODE_Value DB_MODE_READ
1061 #define INIT_PROMPT_Value DBPROMPT_NOPROMPT
1062 #define INIT_PROTECTION_LEVEL_Value 0
1063 #define INIT_PROVIDERSTRING_Value OLESTR("")
1064 #define INIT_TIMEOUT_Value 0
1065 #define LITERALBOOKMARKS_Value ATL_VARIANT_FALSE
1066 #define LITERALIDENTITY_Value ATL_VARIANT_FALSE
1067 #define MAXINDEXSIZE_Value 0
1068 #define MAXOPENROWS_Value 0
1069 #define MAXPENDINGROWS_Value 0
1070 #define MAXROWS_Value 0
1071 #define MAXROWSIZE_Value 0
1072 #define MAXROWSIZEINCLUDESBLOB_Value ATL_VARIANT_FALSE
1073 #define MAXTABLESINSELECT_Value 0
1074 #define MAYWRITECOLUMN_Value ATL_VARIANT_FALSE
1075 #define MEMORYUSAGE_Value 0
1076 #define MULTIPLEPARAMSETS_Value ATL_VARIANT_FALSE
1077 #define MULTIPLERESULTS_Value 0
1078 #define MULTIPLESTORAGEOBJECTS_Value ATL_VARIANT_FALSE
1079 #define MULTITABLEUPDATE_Value ATL_VARIANT_FALSE
1080 #define NOTIFICATIONGRANULARITY_Value DBPROPVAL_NT_SINGLEROW
1081 #define NOTIFICATIONPHASES_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER | DBPROPVAL_NP_FAILEDTODO | DBPROPVAL_NP_DIDEVENT
1082 #define NOTIFYCOLUMNSET_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1083 #define NOTIFYROWDELETE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1084 #define NOTIFYROWFIRSTCHANGE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1085 #define NOTIFYROWINSERT_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1086 #define NOTIFYROWRESYNCH_Value 0
1087 #define NOTIFYROWSETRELEASE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1088 #define NOTIFYROWSETFETCHPOSITIONCHANGE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1089 #define NOTIFYROWUNDOCHANGE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1090 #define NOTIFYROWUNDODELETE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1091 #define NOTIFYROWUNDOINSERT_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1092 #define NOTIFYROWUPDATE_Value DBPROPVAL_NP_OKTODO | DBPROPVAL_NP_ABOUTTODO | DBPROPVAL_NP_SYNCHAFTER
1093 #define NULLCOLLATION_Value 0
1094 #define OLEOBJECTS_Value 0
1095 #define ORDERBYCOLUMNSINSELECT_Value ATL_VARIANT_FALSE
1096 #define ORDEREDBOOKMARKS_Value ATL_VARIANT_FALSE
1097 #define OTHERINSERT_Value ATL_VARIANT_FALSE
1098 #define OTHERUPDATEDELETE_Value ATL_VARIANT_FALSE
1099 #define OUTPUTPARAMETERAVAILABILITY_Value 0
1100 #define OWNINSERT_Value ATL_VARIANT_FALSE
1101 #define OWNUPDATEDELETE_Value ATL_VARIANT_FALSE
1102 #define PERSISTENTIDTYPE_Value 0
1103 #define PREPAREABORTBEHAVIOR_Value 0
1104 #define PREPARECOMMITBEHAVIOR_Value 0
1105 #define PROCEDURETERM_Value OLESTR("")
1106 #define PROVIDERNAME_Value OLESTR("")
1107 #define PROVIDEROLEDBVER_Value OLESTR("02.60")
1108 #define PROVIDERVER_Value OLESTR("01.00")
1109 #define QUICKRESTART_Value ATL_VARIANT_FALSE
1110 #define QUOTEDIDENTIFIERCASE_Value 0
1111 #define REENTRANTEVENTS_Value ATL_VARIANT_FALSE
1112 #define REMOVEDELETED_Value ATL_VARIANT_FALSE
1113 #define REPORTMULTIPLECHANGES_Value ATL_VARIANT_FALSE
1114 #define RETURNPENDINGINSERTS_Value ATL_VARIANT_FALSE
1115 #define ROWRESTRICT_Value ATL_VARIANT_FALSE
1116 #define ROWSETCONVERSIONSONCOMMAND_Value ATL_VARIANT_TRUE
1117 #define ROWTHREADMODEL_Value 0
1118 #define SCHEMATERM_Value OLESTR("")
1119 #define SCHEMAUSAGE_Value 0
1120 #define SERVERCURSOR_Value ATL_VARIANT_FALSE
1121 #define SESS_AUTOCOMMITISOLEVELS_Value 0
1122 #define SQLSUPPORT_Value 0
1123 #define STRONGIDENTITY_Value ATL_VARIANT_FALSE
1124 #define STRUCTUREDSTORAGE_Value 0
1125 #define SUBQUERIES_Value 0
1126 #define SUPPORTEDTXNDDL_Value 0
1127 #define SUPPORTEDTXNISOLEVELS_Value 0
1128 #define SUPPORTEDTXNISORETAIN_Value 0
1129 #define TABLETERM_Value OLESTR("")
1130 #define TBL_TEMPTABLE_Value ATL_VARIANT_FALSE
1131 #define TRANSACTEDOBJECT_Value ATL_VARIANT_FALSE
1132 #define UPDATABILITY_Value 0
1133 #define USERNAME_Value OLESTR("")
1134 // 1.5
1135 #define FILTERCOMPAREOPS_Value 0
1136 #define FINDCOMPAREOPS_Value 0
1137 #define IChapteredRowset_Value ATL_VARIANT_FALSE
1138 #define IDBAsynchStatus_Value ATL_VARIANT_FALSE
1139 #define IRowsetFind_Value ATL_VARIANT_FALSE
1140 #define IRowsetView_Value ATL_VARIANT_FALSE
1141 #define IViewChapter_Value ATL_VARIANT_FALSE
1142 #define IViewFilter_Value ATL_VARIANT_FALSE
1143 #define IViewRowset_Value ATL_VARIANT_FALSE
1144 #define IViewSort_Value ATL_VARIANT_FALSE
1145 #define INIT_ASYNCH_Value 0
1146 #define MAXOPENCHAPTERS_Value 0
1147 #define MAXORSINFILTER_Value 0
1148 #define MAXSORTCOLUMNS_Value 0
1149 #define ROWSET_ASYNCH_Value 0
1150 #define SORTONINDEX_Value ATL_VARIANT_FALSE
1151 // 2.0
1152 #define IMultipleResults_Value ATL_VARIANT_FALSE
1153 #define DATASOURCE_TYPE_Value 0
1154 //MDPROP
1155 #define AXES_Value 0
1156 #define FLATTENING_SUPPORT_Value 0
1157 #define MDX_JOINCUBES_Value 0
1158 #define NAMED_LEVELS_Value 0
1159 //#define RANGEROWSET_Value 0
1160 #define MDX_SLICER_Value 0
1161 //#define MDX_CUBEQUALIFICATION_Value
1162 #define MDX_OUTERREFERENCE_Value 0
1163 #define MDX_QUERYBYPROPERTY_Value ATL_VARIANT_FALSE
1164 #define MDX_CASESUPPORT_Value 0
1165 #define MDX_STRING_COMPOP_Value 0
1166 #define MDX_DESCFLAGS_Value 0
1167 #define MDX_SET_FUNCTIONS_Value 0
1168 #define MDX_MEMBER_FUNCTIONS_Value 0
1169 #define MDX_NUMERIC_FUNCTIONS_Value 0
1170 #define MDX_FORMULAS_Value 0
1171 #define AGGREGATECELL_UPDATE_Value 0
1172 //#define MDX_AGGREGATECELL_UPDATE_Value
1173 #define MDX_OBJQUALIFICATION_Value 0
1174 #define MDX_NONMEASURE_EXPRESSONS_Value 0
1175 // DBPROP
1176 #define ACCESSORDER_Value 0
1177 #define BOOKMARKINFO_Value 0
1178 #define INIT_CATALOG_Value OLESTR("")
1179 #define ROW_BULKOPS_Value 0
1180 #define PROVIDERFRIENDLYNAME_Value OLESTR("")
1181 #define LOCKMODE_Value 0
1182 #define MULTIPLECONNECTIONS_Value ATL_VARIANT_FALSE
1183 #define UNIQUEROWS_Value ATL_VARIANT_FALSE
1184 #define SERVERDATAONINSERT_Value ATL_VARIANT_FALSE
1185 //#define STORAGEFLAGS_Value
1186 #define CONNECTIONSTATUS_Value 0
1187 #define ALTERCOLUMN_Value 0
1188 #define COLUMNLCID_Value 0
1189 #define RESETDATASOURCE_Value 0
1190 #define INIT_OLEDBSERVICES_Value 0
1191 #define IRowsetRefresh_Value ATL_VARIANT_FALSE
1192 #define SERVERNAME_Value OLESTR("")
1193 #define IParentRowset_Value ATL_VARIANT_FALSE
1194 #define HIDDENCOLUMNS_Value 0
1195 #define PROVIDERMEMORY_Value ATL_VARIANT_FALSE
1196 #define CLIENTCURSOR_Value ATL_VARIANT_FALSE
1197 // 2.1
1198 #define TRUSTEE_USERNAME_Value OLESTR("")
1199 #define TRUSTEE_AUTHENTICATION_Value OLESTR("")
1200 #define TRUSTEE_NEWAUTHENTICATION_Value OLESTR("")
1201 #define IRow_Value ATL_VARIANT_FALSE
1202 #define IRowChange_Value ATL_VARIANT_FALSE
1203 #define IRowSchemaChange_Value ATL_VARIANT_FALSE
1204 #define IGetRow_Value ATL_VARIANT_FALSE
1205 #define IScopedOperations_Value ATL_VARIANT_FALSE
1206 #define IBindResource_Value ATL_VARIANT_FALSE
1207 #define ICreateRow_Value ATL_VARIANT_FALSE
1208 #define INIT_BINDFLAGS_Value 0
1209 #define INIT_LOCKOWNER_Value OLESTR("")
1210 #define GENERATEURL_Value 0
1211 //#define IDBBinderProperties_Value
1212 #define IColumnsInfo2_Value ATL_VARIANT_FALSE
1213 //#define IRegisterProvider_Value
1214 #define IGetSession_Value ATL_VARIANT_FALSE
1215 #define IGetSourceRow_Value ATL_VARIANT_FALSE
1216 #define IRowsetCurrentIndex_Value ATL_VARIANT_FALSE
1217 #define OPENROWSETSUPPORT_Value 0
1218 #define COL_ISLONG_Value ATL_VARIANT_FALSE
1219 // 2.5
1220 //#define COL_SEED_Value
1221 //#define COL_INCREMENT_Value
1222 #define INIT_GENERALTIMEOUT_Value 0
1223 #define COMSERVICES_Value 0
1224 // 2.6
1225 #define OUTPUTSTREAM_Value NULL
1226 #define OUTPUTENCODING_Value NULL
1227 #define TABLESTATISTICS_Value 0
1228 #define SKIPROWCOUNTRESULTS_Value ATL_VARIANT_FALSE
1229 #define IRowsetBookmark_Value ATL_VARIANT_FALSE
1230 #define VISUALMODE_Value MDPROPVAL_VISUAL_MODE_DEFAULT
1231 
1232 
1233 #define OUT_OF_LINE virtual
1234 
1235 #define BEGIN_PROPSET_MAP(Class) \
1236  static ATL::UPROPSET * _GetPropSet (ULONG * pNumPropSets, ULONG * pcElemPerSupported, ATL::UPROPSET * pSet =
1237  NULL, GUID * pguidSet = NULL) \
1238  {
1239  \
1240 typedef Class _PropSetClass;
1241  \
1242 ULONG & cElemsMax = *pcElemPerSupported;
1243  \
1244 cElemsMax = 0;
1245  \
1246 ULONG nCurProp = 0;
1247  \
1248 int cRemainder = 0;
1249  \
1250 if (pguidSet == NULL)
1251  \
1252 pguidSet = (GUID *) & GUID_NULL;
1253 
1254 
1255 #define BEGIN_PROPERTY_SET_EX(guid, flags) \
1256  if (pNumPropSets != NULL)
1257  \
1258  {
1259  \
1260 pSet[nCurProp].pPropSet = &guid;
1261  \
1262 pSet[nCurProp].dwFlags = flags;
1263  \
1264 pSet[nCurProp].bIsChained = false;
1265  \
1266 }
1267  \
1268 static const ATL::UPROPINFO aProperty
1269 ##guid[] = \
1270  {
1271 
1272 
1273 #define BEGIN_PROPERTY_SET(guid) BEGIN_PROPERTY_SET_EX(guid, 0)
1274 
1275 //DBPROP_ macros
1276 
1277 #define PROPERTY_INFO_ENTRY_EX(dwPropID, vt, dwFlags, value, options) DBPROP_##dwPropID, IDS_DBPROP_##dwPropID, vt, dwFlags, (DWORD_PTR)value, (DBPROPOPTIONS)options,
1278 
1279 #define PROPERTY_INFO_ENTRY_VALUE(dwPropID, value) PROPERTY_INFO_ENTRY_EX(dwPropID, dwPropID##_Type, dwPropID##_Flags, value, 0)
1280 
1281 #define PROPERTY_INFO_ENTRY_VALUE_FLAGS(dwPropID, value, dwFlags) PROPERTY_INFO_ENTRY_EX(dwPropID, dwPropID##_Type, dwFlags, value, 0)
1282 
1283 #define PROPERTY_INFO_ENTRY(dwPropID) PROPERTY_INFO_ENTRY_VALUE(dwPropID, dwPropID##_Value)
1284 
1285 
1286 //MDPROP_ macros
1287 
1288 #define MDPROPERTY_INFO_ENTRY_EX(dwPropID, vt, dwFlags, value, options) MDPROP_##dwPropID, IDS_MDPROP_##dwPropID, vt, dwFlags, (DWORD_PTR)value, (DBPROPOPTIONS)options,
1289 
1290 #define MDPROPERTY_INFO_ENTRY_VALUE(dwPropID, value) MDPROPERTY_INFO_ENTRY_EX(dwPropID, dwPropID##_Type, dwPropID##_Flags, value, 0)
1291 
1292 #define MDPROPERTY_INFO_ENTRY_VALUE_FLAGS(dwPropID, value, dwFlags) MDPROPERTY_INFO_ENTRY_EX(dwPropID, dwPropID##_Type, dwFlags, value, 0)
1293 
1294 #define MDPROPERTY_INFO_ENTRY(dwPropID) MDPROPERTY_INFO_ENTRY_VALUE(dwPropID, dwPropID##_Value)
1295 
1296 
1297 #define END_PROPERTY_SET(guid) \
1298  };
1299  \
1300 if (pNumPropSets != NULL)
1301  \
1302  {
1303  \
1304 pSet[nCurProp].pUPropInfo = (ATL::UPROPINFO *) aProperty
1305 ##guid; \
1306  pSet[nCurProp].cUPropInfo = sizeof (aProperty
1307 ##guid) / sizeof(ATL::UPROPINFO); \
1308  cRemainder = (pSet[nCurProp].cUPropInfo % 32) ? 1 : 0;
1309  \
1310 if (cElemsMax < (pSet[nCurProp].cUPropInfo / 32 + cRemainder)) \
1311  {
1312  \
1313 cElemsMax = (pSet[nCurProp].cUPropInfo / 32 + cRemainder); \
1314 }
1315  \
1316 }
1317  \
1318 nCurProp++;
1319 
1320 #define CHAIN_PROPERTY_SET(ChainClass) \
1321  ULONG cPropSets
1322 ##ChainClass, cElsSupported##ChainClass; \
1323  int cSets
1324 ##ChainClass = (int)(DWORD_PTR)ChainClass::_GetPropSet(NULL, &cElsSupported##ChainClass); \
1325  if (pNumPropSets != NULL) \
1326  {
1327  \
1328 ATL::UPROPSET * pSetA =
1329  (ATL::UPROPSET *) _alloca (sizeof (ATL::UPROPSET) * cSets
1330 ##ChainClass); \
1331  ATL::UPROPSET * pSetTemp =
1332  ChainClass::_GetPropSet (&cPropSets
1333 ##ChainClass, &cElsSupported##ChainClass, pSetA); \
1334  cElemsMax =
1335  (cElemsMax <
1336  cElsSupported
1337 ##ChainClass) ? cElsSupported##ChainClass : cElemsMax; \
1338  ATLASSERT (pSetTemp);
1339  \
1340 for (ULONG iSet =
1341  nCurProp;
1342  iSet <
1343  nCurProp +
1344  cPropSets
1345 ##ChainClass; iSet++) \
1346  {
1347  \
1348 pSet[iSet].
1349  pPropSet =
1350  pSetTemp[iSet
1351  -
1352  nCurProp].
1353  pPropSet;
1354  \
1355 pSet[iSet].
1356  dwFlags =
1357  pSetTemp[iSet
1358  -
1359  nCurProp].
1360  dwFlags;
1361  \
1362 pSet[iSet].
1363  pUPropInfo =
1364  pSetTemp[iSet
1365  -
1366  nCurProp].
1367  pUPropInfo;
1368  \
1369 pSet[iSet].
1370  cUPropInfo =
1371  pSetTemp[iSet
1372  -
1373  nCurProp].
1374  cUPropInfo;
1375  \
1376 pSet[iSet].
1377  bIsChained =
1378  true; \
1379 }
1380  \
1381 }
1382  \
1383 nCurProp +=
1384  cSets
1385 ##ChainClass;
1386 
1387 #define END_PROPSET_MAP() \
1388  if
1389  (pNumPropSets
1390  != NULL) \
1391  {
1392  \
1393 if
1394  (IsEqualGUID
1395  (*pguidSet,
1396  GUID_NULL))
1397  \
1398  {
1399  \
1400 *pNumPropSets
1401  = nCurProp;
1402  \
1403 return pSet;
1404  \
1405 }
1406  \
1407  else
1408  \
1409  {
1410  \
1411 *pNumPropSets
1412  = 1;
1413  \
1414 UINT i = 0;
1415  \
1416 for (;
1417  i <
1418  sizeof
1419  (pSet)
1420  /
1421  sizeof
1422  (ATL::
1423  UPROPSET)
1424  &&
1425  IsEqualGUID
1426  (*
1427  (pSet
1428  [i].
1429  pPropSet),
1430  *pguidSet);
1431  i++);
1432  \
1433 return (i ==
1434  sizeof
1435  (pSet)
1436  /
1437  sizeof
1438  (ATL::
1439  UPROPSET))
1440  ? &pSet[0] :
1441  &pSet[i]; \
1442 }
1443  \
1444 }
1445  \
1446 return
1447  (ATL::
1448  UPROPSET
1449  *)
1450  (DWORD_PTR)
1451  nCurProp; \
1452 }
1453 
1454 
1455 
1456 // For DataSource flags IDBInitialize::m_dwStatus
1457  enum
1459  {
1460 DSF_MASK_INIT = 0xFFFFF00F, // Mask
1461  // for
1462  // stuff
1463  // lasting
1464  // over
1465  // init/uninit.
1466  DSF_PERSIST_DIRTY = 0x00000001, // Set
1467  // if
1468  // init
1469  // string
1470  // changes.
1471  DSF_INITIALIZED = 0x00000010, // Have
1472  // we
1473  // been
1474  // initialized.
1475  };
1476 
1477 
1478 #define DBID_USE_GUID_OR_PGUID(e) \
1479  ((1 << (e)) &
1480  \
1481 (1 <<
1482  DBKIND_GUID
1483  \
1484 |1 <<
1485  DBKIND_GUID_NAME
1486  \
1487 |1 <<
1489  \
1490 |1 <<
1492  \
1493 |1 <<
1495 
1496 
1497 #define DBID_USE_GUID(e) \
1498  ((1 << (e)) &
1499  \
1500 (1 <<
1501  DBKIND_GUID
1502  \
1503 |1 <<
1504  DBKIND_GUID_NAME
1505  \
1506 |1 <<
1508 
1509 
1510 #define DBID_USE_PGUID(e) \
1511  ((1 << (e)) &
1512  \
1513 (1 <<
1515  \
1516 |1 <<
1518 
1519 
1520 #define DBID_USE_NAME(e) \
1521  ((1 << (e)) &
1522  \
1523 (1 <<
1524  DBKIND_NAME
1525  \
1526 |1 <<
1527  DBKIND_GUID_NAME
1528  \
1529 |1 <<
1531 
1532 
1533 #define DBID_USE_PROPID(e) \
1534  ((1 << (e)) &
1535  \
1536 (1 <<
1538  \
1539 |1 <<
1541  \
1542 |1 <<
1544 
1545 
1546 // Bookmark can be either guid or pguid.
1547 #define DBID_IS_BOOKMARK(dbid) \
1548  (DBID_USE_GUID
1549  (dbid.eKind)
1550  && dbid.
1551  uGuid.guid ==
1552  DBCOL_SPECIALCOL
1553 
1554  ||DBID_USE_PGUID
1555  (dbid.eKind)
1556  && *dbid.
1557  uGuid.
1558  pguid ==
1559  DBCOL_SPECIALCOL)
1560 
1561 
1562 #define DivDword(dw) (dw >> 5) // dw / 32 = dw / (sizeof(DWORD)*8)
1563 #define ModDword(dw) (dw & (32-1)) // dw % 32
1564 #define DwordSizeofBits(nBits) (nBits/32+1) // Use in array declarations
1565 #define CLEARBITARRAY( rgdwFlags ) memset( rgdwFlags, 0, sizeof(rgdwFlags) )
1566 
1567 template <
1568  class T >
1569 
1570 BOOL
1571  InRange (const
1572  T &
1573  val,
1574  const
1575  T &
1576  valMin,
1577  const
1578  T &
1579  valMax)
1580 
1581  {
1582 
1583 return
1584  (valMin <= val
1585  && val <=
1586  valMax);
1587 }
1588 
1589 // Implementation Class
1590  class
1591  CBitFieldOps
1592  {
1593 
1594 public:
1595 void
1596  SETBIT (DWORD
1597  rgdwFlags
1598  [],
1599  const
1600  DWORD
1601  dwBit)
1602 
1603  {
1604 
1605 rgdwFlags
1606  [DivDword
1607  (dwBit)] |=
1608  1 <<
1609  ModDword
1610  (dwBit);
1611 
1612 }
1613 
1614 void
1615  CLEARBIT
1616  (DWORD
1617  rgdwFlags[],
1618  const DWORD
1619  dwBit)
1620  {
1621 
1622 rgdwFlags
1623  [DivDword
1624  (dwBit)] &=
1625  ~(1 <<
1626  ModDword
1627  (dwBit));
1628 
1629 }
1630 
1631 DWORD
1632  TESTBIT (const
1633  DWORD
1634  rgdwFlags
1635  [],
1636  const
1637  DWORD
1638  dwBit)
1639 
1640  {
1641 
1642  // old//Note:
1643  // Not {0,1},
1644  // but from
1645  // {0...2^32-1}.
1646  // Note: Now
1647  // returns
1648  // {0,1}.
1649  return
1650  (rgdwFlags
1651  [DivDword
1652  (dwBit)] &
1653  (1 <<
1654  ModDword
1655  (dwBit))) !=
1656  0;
1657 }
1658 
1659 };
1660 
1661 
1662 // Implementation Class
1663  class CDBIDOps
1664 
1665  {
1666 
1667 public:
1668 HRESULT
1669  CompareDBIDs
1670  (const DBID *
1671  pdbid1,
1672  const DBID *
1673  pdbid2)
1674  {
1675 
1676  // Array of
1677  // valid
1678  // eKind
1679  // matches,
1680  // in
1681  // addition
1682  // to
1683  // matching
1684  // exactly.
1685  static const
1686  BYTE
1687  s_rgbKind[] =
1688 
1689  {
1690 
1691 DBKIND_PGUID_NAME, // DBKIND_GUID_NAME
1692  DBKIND_PGUID_PROPID, // DBKIND_GUID_PROPID
1693  DBKIND_NAME, // DBKIND_NAME
1694  DBKIND_GUID_NAME, // DBKIND_PGUID_NAME
1695  DBKIND_GUID_PROPID, // DBKIND_PGUID_PROPID
1696  DBKIND_PROPID, // DBKIND_PROPID
1697  DBKIND_GUID // DBKIND_GUID
1698  };
1699 
1700 
1701 if (!pdbid1
1702  ||
1703  !pdbid2)
1704 
1705  return
1706  S_FALSE;
1707 
1708  // Assume a
1709  // match, and
1710  // discard
1711  // early if
1712  // we can.
1713  DBKIND tmp1 =
1714  0;
1715 
1716 DBKIND tmp2 =
1717  (DBKIND)
1718  (sizeof
1719  (s_rgbKind) /
1720  sizeof
1721  (*s_rgbKind));
1722 
1723 if (!InRange
1724  (pdbid2->
1725  eKind,
1726  tmp1,
1727  tmp2))
1728  {
1729 
1730 ATLTRACE
1731  (atlTraceDBProvider,
1732  0,
1733  _T
1734  ("Column ID out of Range\n"));
1735 
1736 return
1737  E_FAIL;
1738 }
1739 
1740 if (pdbid1->
1741  eKind !=
1742  pdbid2->
1743  eKind
1744  &&pdbid1->
1745  eKind !=
1746  s_rgbKind
1747  [pdbid2->
1748  eKind])
1749 
1750  return
1751  S_FALSE;
1752 
1753 
1754 if
1756  (pdbid1->
1757  eKind))
1758  {
1759 
1760 if
1762  (pdbid2->
1763  eKind))
1764  return
1765  S_FALSE;
1766  // Compare
1767  // GUIDs.
1768  // Note that
1769  // _GUID_ is
1770  // equivalent
1771  // to
1772  // _PGUID_.
1773  if
1774  (!InlineIsEqualGUID
1775  (
1777  (pdbid1->
1778  eKind) ?
1779  *(pdbid1->
1780  uGuid.
1781  pguid) :
1782  pdbid1->
1783  uGuid.guid,
1784 
1786  (pdbid2->
1787  eKind) ?
1788  *(pdbid2->
1789  uGuid.
1790  pguid) :
1791  pdbid2->
1792  uGuid.
1793  guid))
1794  return
1795  S_FALSE;
1796 }
1797 
1798 if
1799  (DBID_USE_NAME
1800  (pdbid1->
1801  eKind))
1802  {
1803 
1804 if
1805  (!DBID_USE_NAME
1806  (pdbid2->
1807  eKind))
1808  return
1809  S_FALSE;
1810  // Compare
1811  // names.
1812  // Need to
1813  // check if 1
1814  // is null
1815  // and the
1816  // other is
1817  // not.
1818  if ((pdbid1->
1819  uName.
1820  pwszName
1821  ==
1822  NULL) !=
1823  (pdbid2->
1824  uName.
1825  pwszName
1826  ==
1827  NULL))
1828  return
1829  S_FALSE;
1830  // Since the
1831  // above
1832  // check does
1833  // not rule
1834  // out both
1835  // being
1836  // null,
1837  // which is
1838  // a valid
1839  // comparison,
1840  // and wcscmp
1841  // will GPF
1842  // if they
1843  // were, we
1844  // need
1845  // to check
1846  // for valid
1847  // pointers
1848  if (pdbid1->
1849  uName.
1850  pwszName
1851  &&
1852  pdbid2->
1853  uName.
1854  pwszName)
1855 
1856  {
1857 
1858  // Assume
1859  // null-terminated.
1860  // Assume
1861  // LCID match
1862  // is OK
1863  // (note diff
1864  // with
1865  // lstrcmp(),
1866  // CompareString().)
1867  if (wcscmp
1868  (pdbid1->
1869  uName.
1870  pwszName,
1871  pdbid2->
1872  uName.
1873  pwszName)
1874  !=
1875  0)
1876  return
1877  S_FALSE;
1878 }
1879 
1880 }
1881 
1882 if
1884  (pdbid1->
1885  eKind))
1886  {
1887 
1888 if
1889  (!DBID_USE_PROPID
1890  (pdbid2->
1891  eKind))
1892  return
1893  S_FALSE;
1894  // Compare
1895  // PROPID.
1896  if (pdbid1->
1897  uName.
1898  ulPropid
1899  !=
1900  pdbid2->
1901  uName.
1902  ulPropid)
1903 
1904  return
1905  S_FALSE;
1906 }
1907 
1908 
1909  // No reason
1910  // to
1911  // discard,
1912  // so must
1913  // have
1914  // matched
1915  // each field
1916  // successfully.
1917  return S_OK;
1918 }
1919 
1920 
1921 static
1922  HRESULT
1923  IsValidDBID
1924  (const DBID *
1925  pdbid1)
1926  {
1927 
1928 ATLASSERT
1929  (pdbid1);
1930 
1931 
1932 if (pdbid1
1933  &&
1934 
1935 ((pdbid1->eKind == DBKIND_GUID_NAME) ||
1936 (pdbid1->eKind == DBKIND_GUID_PROPID) ||
1937 (pdbid1->eKind == DBKIND_NAME) ||
1938 (pdbid1->eKind == DBKIND_PGUID_NAME) ||
1939 (pdbid1->eKind == DBKIND_PGUID_PROPID) ||
1940 (pdbid1->eKind == DBKIND_PROPID) ||
1941 (pdbid1->eKind == DBKIND_GUID)))
1942  return S_OK;
1943  else
1944 
1945 return
1946  S_FALSE;
1947 }
1948 
1949 HRESULT
1950  CopyDBIDs
1951  (DBID *
1952  pdbidDest,
1953  const DBID *
1954  pdbidSrc)
1955  {
1956 
1957 size_t
1958  cwchBuffer;
1959 
1960 
1961 ATLASSERT
1962  (pdbidDest
1963  || pdbidSrc);
1964 
1965 
1966 if
1967  (!pdbidDest
1968  || !pdbidSrc)
1969 
1970  return
1971  S_FALSE;
1972 
1973  // Save
1974  // eKind
1975  pdbidDest->
1976  eKind =
1977  pdbidSrc->
1978  eKind;
1979 
1980 
1981 switch
1982  (pdbidSrc->
1983  eKind)
1984  {
1985 
1986 
1987 case DBKIND_GUID_NAME:
1988 
1989 pdbidDest->
1990  uGuid.guid =
1991  pdbidSrc->
1992  uGuid.guid;
1993 
1994 cwchBuffer =
1995  ocslen
1996  (pdbidSrc->
1997  uName.
1998  pwszName);
1999 
2000 cwchBuffer++;
2001 
2002 pdbidDest->
2003  uName.
2005  (PWSTR)
2006  CoTaskMemAlloc
2007  (cwchBuffer *
2008  sizeof
2009  (WCHAR));
2010 
2011 if
2012  (pdbidDest->
2013  uName.
2014  pwszName)
2015  memcpy
2016  (pdbidDest->
2017  uName.
2018  pwszName,
2019  pdbidSrc->
2020  uName.
2021  pwszName,
2022  cwchBuffer *
2023  sizeof
2024  (WCHAR));
2025  else
2026 
2028 break;
2029 
2030 case DBKIND_GUID_PROPID:
2031 
2032 pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
2033 pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
2034 break;
2035 case DBKIND_NAME:
2036 
2037 cwchBuffer =
2038  ocslen
2039  (pdbidSrc->
2040  uName.
2042 
2044 
2045 pdbidDest->
2046  uName.
2047  pwszName =
2048  (PWSTR)
2049  CoTaskMemAlloc
2050  (cwchBuffer *
2051  sizeof
2052  (WCHAR));
2053 
2054 if
2055  (pdbidDest->
2056  uName.
2057  pwszName)
2058  memcpy
2059  (pdbidDest->
2060  uName.
2061  pwszName,
2062  pdbidSrc->
2063  uName.
2064  pwszName,
2065  cwchBuffer *
2066  sizeof
2067  (WCHAR));
2068  else
2069 
2070 return E_OUTOFMEMORY;
2071 break;
2072 case DBKIND_PGUID_NAME:
2073 
2074 pdbidDest->
2075  uGuid.pguid =
2076  (GUID *)
2077  CoTaskMemAlloc
2078  (sizeof
2079  (GUID));
2080 
2081 if
2082  (pdbidDest->
2083  uGuid.
2084  pguid)
2085  {
2086 
2087 *(pdbidDest->
2088  uGuid.
2089  pguid) =
2090  *(pdbidSrc->
2091  uGuid.
2092  pguid);
2093 
2094 cwchBuffer =
2095  ocslen
2096  (pdbidSrc->
2097  uName.
2098  pwszName);
2099 
2100 cwchBuffer++;
2101 
2102 pdbidDest->
2103  uName.
2104  pwszName =
2105  (PWSTR)
2106  CoTaskMemAlloc
2107  (cwchBuffer *
2108  sizeof
2109  (WCHAR));
2110 
2111 if
2112  (pdbidDest->
2113  uName.
2114  pwszName)
2115  {
2116 
2117 memcpy
2118  (pdbidDest->
2119  uName.
2120  pwszName,
2121  pdbidSrc->
2122  uName.
2123  pwszName,
2124  cwchBuffer *
2125  sizeof
2126  (WCHAR));
2127 
2128 break;
2129 }
2130 
2131  else
2132 
2133  {
2134 
2135 CoTaskMemFree
2136  (pdbidDest->
2137  uGuid.pguid);
2138 
2139 pdbidDest->
2140  uGuid.pguid =
2141  NULL;
2142 }
2143 
2144 }
2145 
2146 return E_OUTOFMEMORY;
2147 case DBKIND_PGUID_PROPID:
2148 
2149 pdbidDest->
2150  uGuid.pguid =
2151  (GUID *)
2152  CoTaskMemAlloc
2153  (sizeof
2154  (GUID));
2155 
2156 if
2157  (pdbidDest->
2158  uGuid.
2159  pguid)
2160  *(pdbidDest->
2161  uGuid.
2162  pguid) =
2163  *(pdbidSrc->
2164  uGuid.
2165  pguid);
2166  else
2167 
2168 return E_OUTOFMEMORY;
2169 pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
2170 break;
2171 case DBKIND_PROPID:
2172 
2173 pdbidDest->uName.ulPropid = pdbidSrc->uName.ulPropid;
2174 break;
2175 case DBKIND_GUID:
2176 
2177 pdbidDest->uGuid.guid = pdbidSrc->uGuid.guid;
2178 break;
2179 default:
2180 
2181 ATLASSERT
2182  (L"Unhandled dbid1.ekind");
2183 
2184 return
2186 }
2187 
2188 
2189 return S_OK;
2190 }
2191 
2192 static GUID *
2193  GetDBIDpGuid
2194  (DBID & dbid)
2195 
2196  {
2197 
2198 GUID * pGuid;
2199 
2200 switch (dbid.
2201  eKind)
2202 
2203  {
2204 
2205 case DBKIND_PGUID_NAME:
2206 
2207 case DBKIND_PGUID_PROPID:
2208 
2209 pGuid = dbid.uGuid.pguid;
2210 break;
2211 case DBKIND_GUID_NAME:
2212 
2213 case DBKIND_GUID_PROPID:
2214 
2215 case DBKIND_GUID:
2216 
2217 pGuid = &(dbid.uGuid.guid);
2218 break;
2219 default:
2220 
2221 pGuid = NULL;
2222 }
2223 
2224 
2225 return
2226  pGuid;
2227 }
2228 
2229 static ULONG
2230  GetPropIDFromDBID
2231  (DBID & dbid)
2232 
2233  {
2234 
2235 switch (dbid.
2236  eKind)
2237 
2238  {
2239 
2240 case DBKIND_GUID_PROPID:
2241 
2242 case DBKIND_PGUID_PROPID:
2243 
2244 case DBKIND_PROPID:
2245 
2246 return dbid.uName.ulPropid;
2247 default:
2248 
2249 return 0;
2250 }
2251 
2252 }
2253 
2254 void
2255  FreeDBIDs
2256  (DBID *
2257  pdbidSrc)
2258  {
2259 
2260 switch
2261  (pdbidSrc->
2262  eKind)
2263  {
2264 
2265 
2266 case DBKIND_GUID_NAME:
2267 
2268 CoTaskMemFree (pdbidSrc->uName.pwszName);
2269 break;
2270 case DBKIND_NAME:
2271 
2272 CoTaskMemFree (pdbidSrc->uName.pwszName);
2273 break;
2274 case DBKIND_PGUID_NAME:
2275 
2276 CoTaskMemFree (pdbidSrc->uGuid.pguid);
2277 CoTaskMemFree (pdbidSrc->uName.pwszName);
2278 break;
2279 case DBKIND_PGUID_PROPID:
2280 
2281 CoTaskMemFree (pdbidSrc->uGuid.pguid);
2282 break;
2283 case DBKIND_GUID_PROPID:
2284 
2285 case DBKIND_PROPID:
2286 
2287 case DBKIND_GUID:
2288 
2289 break;
2290 default:
2291 
2292 ATLASSERT
2293  (L"Unhandled dbid1.ekind");
2294 
2295 break;
2296 }
2297 
2298 }
2299 
2300 };
2301 
2302 
2303 class
2305 
2306  {
2307 
2308 public:
2310  {
2311  }
2312 
2313 HRESULT
2314  FinalConstruct
2315  ()
2316  {
2317 
2318 HRESULT hr
2319  =::
2320  CoCreateInstance
2321  (CLSID_OLEDB_CONVERSIONLIBRARY,
2322  NULL,
2323 
2324 CLSCTX_INPROC_SERVER,
2325  __uuidof
2326  (IDataConvert),
2327  (void **)
2328  &m_spConvert);
2329 
2330 
2331 if (FAILED
2332  (hr))
2333  return hr;
2334 
2335  // Check to
2336  // see if the
2337  // data
2338  // conversion
2339  // routine is
2340  // 2.0
2341  // capable,
2342  // if so.
2343  // Initialize
2344  // the
2345  // conversion
2346  // routine to
2347  // be 2.0.
2348  DCINFO
2349  rgInfo[] =
2350  {
2351  {
2352  DCINFOTYPE_VERSION,
2353  {
2354  VT_UI4, 0, 0,
2355  0, 0x0}
2356  }
2357  };
2358 
2359 CComPtr <
2360  IDCInfo >
2361  spIDCInfo;
2362 
2363 
2364 hr =
2365  m_spConvert->
2366  QueryInterface
2367  (&spIDCInfo);
2368 
2369 if (hr ==
2370  S_OK)
2371  {
2372 
2373 V_UI4 (&rgInfo->vData) = 0x200; // OLEDB
2374  // Version
2375  // 02.00
2376  spIDCInfo->
2377  SetInfo (1,
2378  rgInfo);
2379 
2380 }
2381 
2382 
2383 return hr;
2384 }
2385 
2386 CComPtr <
2387  IDataConvert >
2388  m_spConvert;
2389 
2390 };
2391 
2392 
2393 // IDBCreateSessionImpl
2394 template < class T, class SessionClass >
2395 class ATL_NO_VTABLE IDBCreateSessionImpl: public
2396  IDBCreateSession
2397 
2398  {
2399 
2400 public:
2401 STDMETHOD
2402  (CreateSession)
2403  (IUnknown *
2404  pUnkOuter,
2405 
2406 REFIID riid,
2407 
2408 IUnknown **
2409  ppDBSession)
2410 
2411  {
2412 
2413 ATLTRACE
2414  (atlTraceDBProvider,
2415  2,
2416  _T
2417  ("IDBCreateSessionImpl::CreateSession\n"));
2418 
2419 if
2420  (ppDBSession
2421  ==
2422  NULL)
2423  return
2424  E_INVALIDARG;
2425 
2426 *ppDBSession
2427  = NULL;
2428 
2429 T * pT =
2430  (T *) this;
2431 
2432 if (!
2433  (pT->
2434  m_dwStatus
2435  &
2436  DSF_INITIALIZED))
2437 
2438  {
2439 
2440 ATLTRACE
2441  (atlTraceDBProvider,
2442  0,
2443  _T
2444  ("IDBCreateSessionImpl::CreateSession : Error not initialized\n"));
2445 
2446 *ppDBSession
2447  = NULL;
2448 
2449 return
2450  E_UNEXPECTED;
2451 
2452 }
2453 
2454 CComPolyObject
2455  <
2456  SessionClass >
2457  *pSession;
2458 
2459  // You can't
2460  // QI for an
2461  // interface
2462  // other than
2463  // IUnknown
2464  // when
2465  // aggregating
2466  //
2467  // and
2468  // creating
2469  // the
2470  // object.
2471  // You might
2472  // ask for
2473  // your own
2474  // interface,
2475  //
2476  // which
2477  // would be
2478  // bad.
2479  // Note, we
2480  // return
2481  // DB_E_NOAGGREGATION
2482  // instead
2483  // of
2484  // CLASS_E_NOAGGREGATION
2485  // due to OLE
2486  // DB
2487  // constraints.
2488  if (pUnkOuter
2489  != NULL
2490  &&
2491  !InlineIsEqualUnknown
2492  (riid))
2493  return
2494  DB_E_NOAGGREGATION;
2495 
2496 
2497 HRESULT hr =
2498  CComPolyObject
2499  <
2500  SessionClass
2501  >::
2502  CreateInstance
2503  (pUnkOuter,
2504  &pSession);
2505 
2506 if (SUCCEEDED
2507  (hr))
2508  {
2509 
2510 CComPtr <
2511  IObjectWithSite
2512  > spCreator;
2513 
2514 hr =
2515  pSession->
2516  QueryInterface
2517  (__uuidof
2518  (IObjectWithSite),
2519  (void **)
2520  &spCreator);
2521 
2522 if (SUCCEEDED
2523  (hr))
2524  {
2525 
2526 CComPtr <
2527  IUnknown >
2528  spOuterUnk;
2529 
2530 pT->
2531  QueryInterface
2532  (__uuidof
2533  (IUnknown),
2534  (void **)
2535  &spOuterUnk);
2536 
2537 spCreator->
2538  SetSite
2539  (spOuterUnk);
2540 
2541 hr =
2542  pSession->
2543  QueryInterface
2544  (riid,
2545  (void **)
2546  ppDBSession);
2547 
2548 }
2549  else
2550 
2551 delete
2552  pSession;
2553 }
2554 
2555 return hr;
2556 }
2557 
2558 };
2559 
2560 
2561 // IDBInitializeImpl
2562 template < class T >
2563 class ATL_NO_VTABLE IDBInitializeImpl: public
2564  IDBInitialize
2565 
2566  {
2567 
2568 public:
2570  {
2571 
2572 m_dwStatus =
2573  0;
2574 
2575 m_pCUtlPropInfo
2576  = NULL;
2577 
2578 m_cSessionsOpen
2579  = 0;
2580 }
2581 
2583  ()
2584  {
2585 
2586 delete
2587  m_pCUtlPropInfo;
2588 
2589 }
2590 
2591 
2592 STDMETHOD
2593  (Uninitialize)
2594  (void)
2595  {
2596 
2597 ATLTRACE
2598  (atlTraceDBProvider,
2599  2,
2600  _T
2601  ("IDBInitializeImpl::Uninitialize\n"));
2602 
2603 T * pT =
2604  (T *) this;
2605 
2606 T::
2607  ObjectLock
2608  lock (pT);
2609 
2610 if (pT->
2611  m_cSessionsOpen
2612  != 0)
2613  {
2614 
2615 ATLTRACE
2616  (atlTraceDBProvider,
2617  0,
2618  _T
2619  ("Uninitialized called with Open Sessions\n"));
2620 
2621 return
2622  DB_E_OBJECTOPEN;
2623 
2624 }
2625 
2626 delete m_pCUtlPropInfo;
2627 m_pCUtlPropInfo = NULL;
2628 pT->m_dwStatus |= DSF_PERSIST_DIRTY;
2629 pT->m_dwStatus &= DSF_MASK_INIT; // Clear
2630  // all
2631  // non-init
2632  // flags.
2633  return S_OK;
2634 
2635 }
2636 
2637 
2638 DWORD
2639  m_dwStatus;
2640 
2642  < T >
2643  *m_pCUtlPropInfo;
2644 
2645 LONG
2646  m_cSessionsOpen;
2647 
2648 
2649 STDMETHOD
2650  (Initialize)
2651  (void)
2652  {
2653 
2654 
2655 ATLTRACE
2656  (atlTraceDBProvider,
2657  2,
2658  _T
2659  ("IDBInitializeImpl::Initialize\n"));
2660 
2661 T * pT =
2662  (T *) (this);
2663 
2664 T::
2665  ObjectLock
2666  lock (pT);
2667 
2668 HRESULT hr;
2669 
2670 if (pT->
2671  m_dwStatus
2672  &
2674 
2675  {
2676 
2677 ATLTRACE
2678  (atlTraceDBProvider,
2679  0,
2680  _T
2681  ("IDBInitializeImpl::Initialize Error : Already Initialized\n"));
2682 
2683 return
2684  DB_E_ALREADYINITIALIZED;
2685 
2686 }
2687 
2688 delete
2689  m_pCUtlPropInfo;
2690 
2691 m_pCUtlPropInfo
2692  = NULL;
2693 
2694 ATLTRY
2695  (m_pCUtlPropInfo
2696  =
2697  new
2698  CUtlPropInfo
2699  < T >
2700  ())
2701  if
2702  (m_pCUtlPropInfo
2703  == NULL)
2704  {
2705 
2706 ATLTRACE
2707  (atlTraceDBProvider,
2708  0,
2709  _T
2710  ("IDBInitializeImpl::Initialize Error : OOM\n"));
2711 
2712 return
2713  E_OUTOFMEMORY;
2714 
2715 }
2716 
2717 hr =
2718  m_pCUtlPropInfo->
2719  FInit ();
2720 
2721 if (hr ==
2722  S_OK)
2723  {
2724 
2725 pT->
2726  m_dwStatus |=
2728 
2729 }
2730 
2731  else
2732 
2733  {
2734 
2735 delete
2736  m_pCUtlPropInfo;
2737 
2738 m_pCUtlPropInfo
2739  = NULL;
2740 }
2741 
2742 return hr;
2743 }
2744 
2745 
2746 };
2747 
2748 
2749 
2750 // Implementation Class
2751 
2752 class CPropColID:
2753 public
2754  PROPCOLID,
2755 
2756 public
2757  CDBIDOps
2758  {
2759 
2760 public:
2762 
2763  {
2764 
2765 VariantInit
2766  (&vValue);
2767 }
2768 
2770  ()
2771  {
2772 
2773 FreeDBIDs
2774  (&dbidProperty);
2775 
2776 VariantClear
2777  (&vValue);
2778 }
2779 
2780 bool
2781  operator==
2782  (const
2783  CPropColID &
2784  colId)
2785  {
2786 
2787 return
2788  (CompareDBIDs
2789  (&dbidProperty,
2790  &(colId.
2791  dbidProperty))
2792  ==
2793  S_OK) ? true
2794  : false;
2795 }
2796 
2797 
2798 };
2799 
2800 
2801 class CColumnIds:
2802 public
2803  CDBIDOps,
2804 
2805 public
2806  CAtlArray <
2807  CPropColID >
2808 
2809 
2810  {
2811 
2812 public:
2813 PPROPCOLID
2815 
2816  {
2817 
2818 CPropColID
2819  colID;
2820 
2821 _ATLTRY
2822  {
2823 
2824 Add (colID);
2825 }
2826 
2827 _ATLCATCH (e)
2828 
2829  {
2830 
2831 _ATLDELETEEXCEPTION
2832  (e)
2833  return
2834  NULL;
2835 }
2836 
2837 return
2838  &(GetAt
2839  (GetCount ()
2840  - 1));
2841 }
2842 
2843 HRESULT
2845  (const DBID *
2846  pdbidProp)
2847  {
2848 
2849 for (size_t i
2850  = 0;
2851  i <
2852  GetCount
2853  ();
2854  i++)
2855  {
2856 
2857 if
2858  (CompareDBIDs
2859  (pdbidProp,
2860  &(GetAt (i).
2861  dbidProperty))
2862  == S_OK)
2863  {
2864 
2865 if (i < 0
2866  || i >=
2867  GetCount
2868  ())
2869  return E_FAIL;
2870 
2871 RemoveAt (i);
2872 
2873 return S_OK;
2874 
2875 }
2876 
2877 }
2878 
2879 
2880 return
2881  E_FAIL;
2882 }
2883 
2884 HRESULT
2885  AddColumnId
2886  (DBPROP *
2887  pProp)
2888  {
2889 
2890 CPropColID
2891  colID;
2892 
2893 HRESULT hr =
2894  CopyDBIDs (&
2895  (colID.
2896  dbidProperty),
2897  &
2898  (pProp->
2899  colid));
2900 
2901 if (FAILED
2902  (hr))
2903  return hr;
2904 
2905 colID.
2906  dwOption =
2907  pProp->
2908  dwOptions;
2909 
2910 hr =
2911  VariantCopy (&
2912  (colID.
2913  vValue),
2914  &
2915  (pProp->
2916  vValue));
2917 
2918 if (FAILED
2919  (hr))
2920  return hr;
2921  // return
2922  // (Add(colID))
2923  // ? S_OK :
2924  // E_OUTOFMEMORY;
2925  _ATLTRY
2926  {
2927 
2928 Add (colID);
2929 }
2930 
2931 _ATLCATCH (e)
2932 
2933  {
2934 
2935 _ATLDELETEEXCEPTION
2936  (e);
2937 
2938 return
2939  E_OUTOFMEMORY;
2940 
2941 }
2942 
2943 return S_OK;
2944 }
2945 
2946 HRESULT
2947  AddColumnId
2949  pPropNode)
2950  {
2951 
2952 CPropColID
2953  colID;
2954 
2955 HRESULT hr =
2956  CopyDBIDs (&
2957  (colID.
2958  dbidProperty),
2959  &
2960  (pPropNode->
2961  dbidProperty));
2962 
2963 if (FAILED
2964  (hr))
2965  return hr;
2966 
2967 colID.
2968  dwOption =
2969  pPropNode->
2970  dwOption;
2971 
2972 hr =
2973  VariantCopy (&
2974  (colID.
2975  vValue),
2976  &
2977  (pPropNode->
2978  vValue));
2979 
2980 if (FAILED
2981  (hr))
2982  return hr;
2983  // return
2984  // (Add(colID))
2985  // ? S_OK :
2986  // E_OUTOFMEMORY;
2987  _ATLTRY
2988  {
2989 
2990 Add (colID);
2991 }
2992 
2993 _ATLCATCH (e)
2994 
2995  {
2996 
2997 _ATLDELETEEXCEPTION
2998  (e);
2999 
3000 return
3001  E_OUTOFMEMORY;
3002 
3003 }
3004 
3005 return S_OK;
3006 }
3007 
3008 ULONG
3010  ()
3011  {
3012  return (ULONG)
3013  GetCount ();}
3014 
3015 PPROPCOLID
3016  FindColumnId
3017  (const DBID *
3018  pdbidProp)
3019  {
3020 
3021 for (size_t i
3022  = 0;
3023  i <
3024  GetCount
3025  ();
3026  i++)
3027  {
3028 
3029 if
3030  (CompareDBIDs
3031  (pdbidProp,
3032  &(GetAt (i).
3033  dbidProperty))
3034  ==
3035  S_OK)
3036  return
3037  &(GetAt (i));
3038 
3039 }
3040 
3041 
3042 return NULL;
3043 }
3044 
3045 HRESULT
3046  GetValue
3047  (size_t
3048  iColId,
3049  DWORD *
3050  pdwOptions,
3051  DBID *
3052  pColid,
3053  VARIANT *
3054  pvValue)
3055  {
3056 
3057 HRESULT hr;
3058 
3059 
3060 ATLASSERT
3061  (pdwOptions
3062  && pColid
3063  && pvValue);
3064 
3065 ATLASSERT
3066  (iColId >= 0
3067  && iColId <
3068  GetCount ());
3069 
3070 
3071 CPropColID &
3072  colId =
3073  GetAt
3074  (iColId);
3075 
3076 *pdwOptions =
3077  colId.
3078  dwOption;
3079  // CopyDBIDs(
3080  // pColid,
3081  // &(colId.dbidProperty)
3082  // );
3083  hr =
3084  CopyDBIDs
3085  (pColid,
3086  &(colId.
3087  dbidProperty));
3088 
3089 if (FAILED
3090  (hr)
3091  || hr ==
3092  S_FALSE)
3093 
3094  {
3095 
3096 return hr;
3097 }
3098 
3099 if (FAILED
3100  (hr =
3101  VariantCopy
3102  (pvValue,
3103  &
3104  (colId.
3105  vValue))))
3106 
3107  return hr;
3108 
3109 return S_OK;
3110 
3111 }
3112 
3113 };
3114 
3115 
3116 const ULONG
3118  = 256;
3119 
3120 const DWORD
3122  = 0x00000001;
3123 
3124 // Rules for GetPropertiesArgChk
3125  const DWORD
3127  = 0x00000001;
3128 
3129 
3130 // Implementation Class
3131 template < class T >
3132 class CUtlPropInfo: public
3133  CBitFieldOps,
3134  public
3135  CDBIDOps
3136  {
3137 
3138 public:
3139 enum
3141 
3142  {
3143 
3145  = 0x0001,
3146 
3148  = 0x0002,
3149 
3151  = 0x0004,
3152 
3154  = 0x0008
3155  };
3156 
3157 
3159  ()
3160  {
3161 
3162 m_cUPropSet =
3163  0;
3164 
3165 m_pUPropSet =
3166  NULL;
3167 
3168 
3170  = 0;
3171 
3172 
3174  = 0;
3175 }
3176 
3178  ()
3179  {
3180 
3181 CoTaskMemFree
3182  (m_pUPropSet);
3183 
3184 }
3185 
3186  // Determine
3187  // the number
3188  // of
3189  // description
3190  // buffers
3191  // needed
3192  ULONG
3194  (ULONG
3195  cPropInfoSet,
3196  DBPROPINFOSET
3197  *
3198  pPropInfoSet)
3199 
3200  {
3201 
3202 ULONG
3203  cBuffers = 0;
3204 
3205 
3206 ATLASSERT
3207  (m_pUPropSet);
3208 
3209 ATLASSERT
3210  (cPropInfoSet
3211  &&
3212  pPropInfoSet);
3213 
3214 
3215 for (ULONG
3216  ulSet =
3217  0;
3218  ulSet <
3219  cPropInfoSet;
3220  ulSet++)
3221 
3222  {
3223 
3224 if
3226  (&
3227  (pPropInfoSet
3228  [ulSet].
3229  guidPropertySet))
3230  == S_OK)
3231  {
3232 
3233 if
3234  (pPropInfoSet
3235  [ulSet].
3236  cPropertyInfos
3237  == 0)
3238  {
3239 
3240 for (ULONG ul
3241  = 0;
3242  ul <
3243  m_cPropSetDex;
3244  ul++)
3245  {
3246 
3247 cBuffers +=
3248  m_pUPropSet
3250  [ul]].
3251  cUPropInfo;
3252 }
3253 
3254 }
3255 
3256  else
3257 
3258  {
3259 
3260 cBuffers +=
3261  pPropInfoSet
3262  [ulSet].
3263  cPropertyInfos;
3264 
3265 }
3266 
3267 }
3268 
3269 }
3270 
3271 
3272 return
3273  cBuffers;
3274 }
3275 
3276  // Retrieve
3277  // the
3278  // property
3279  // set
3280  // indexes
3281  // that match
3282  // this
3283  // property
3284  // set.
3285  HRESULT
3287  (const GUID *
3288  pPropertySet)
3289 
3290  {
3291 
3292 DWORD dwFlag
3293  = 0;
3294 
3295 ULONG ulSet;
3296 
3297 
3298 ATLASSERT
3299  (m_cUPropSet
3300  &&
3301  m_pUPropSet);
3302 
3303 ATLASSERT
3304  (m_rgiPropSetDex);
3305 
3306 ATLASSERT
3307  (pPropertySet);
3308 
3309 
3311  = 0;
3312 
3313 
3314 if
3315  (InlineIsEqualGUID
3316  (*pPropertySet,
3317  DBPROPSET_DATASOURCEALL))
3318 
3319  {
3320 
3321 dwFlag =
3322  DBPROPFLAGS_DATASOURCE;
3323 
3324 }
3325 
3326  else
3327  if
3328  (InlineIsEqualGUID
3329  (*pPropertySet,
3330  DBPROPSET_DATASOURCEINFOALL))
3331 
3332  {
3333 
3334 dwFlag =
3335  DBPROPFLAGS_DATASOURCEINFO;
3336 
3337 }
3338 
3339  else
3340  if
3341  (InlineIsEqualGUID
3342  (*pPropertySet,
3343  DBPROPSET_ROWSETALL))
3344 
3345  {
3346 
3347 dwFlag =
3348  DBPROPFLAGS_ROWSET;
3349 
3350 }
3351 
3352  else
3353  if
3354  (InlineIsEqualGUID
3355  (*pPropertySet,
3356  DBPROPSET_DBINITALL))
3357 
3358  {
3359 
3360 dwFlag =
3361  DBPROPFLAGS_DBINIT;
3362 
3363 }
3364 
3365  else
3366  if
3367  (InlineIsEqualGUID
3368  (*pPropertySet,
3369  DBPROPSET_SESSIONALL))
3370 
3371  {
3372 
3373 dwFlag =
3374  DBPROPFLAGS_SESSION;
3375 
3376 }
3377 
3378  else
3379  if
3380  (InlineIsEqualGUID
3381  (*pPropertySet,
3382  DBPROPSET_COLUMNALL))
3383 
3384  {
3385 
3386 dwFlag =
3387  DBPROPFLAGS_COLUMN;
3388 
3389 }
3390 
3391  else
3392  if
3393  (InlineIsEqualGUID
3394  (*pPropertySet,
3395  DBPROPSET_INDEXALL))
3396 
3397  {
3398 
3399 dwFlag =
3400  DBPROPFLAGS_INDEX;
3401 
3402 }
3403 
3404  else
3405  if
3406  (InlineIsEqualGUID
3407  (*pPropertySet,
3408  DBPROPSET_TABLEALL))
3409 
3410  {
3411 
3412 dwFlag =
3413  DBPROPFLAGS_TABLE;
3414 
3415 }
3416 
3417  else
3418  if
3419  (InlineIsEqualGUID
3420  (*pPropertySet,
3421  DBPROPSET_TRUSTEEALL))
3422 
3423  {
3424 
3425 dwFlag =
3426  DBPROPFLAGS_TRUSTEE;
3427 
3428 }
3429 
3430  else
3431  if
3432  (InlineIsEqualGUID
3433  (*pPropertySet,
3434  DBPROPSET_VIEWALL))
3435 
3436  {
3437 
3438 dwFlag =
3439  DBPROPFLAGS_VIEW;
3440 
3441 }
3442 
3443  else // No
3444  // scan
3445  // required,
3446  // just
3447  // look
3448  // for
3449  // match.
3450  {
3451 
3452 for (ulSet =
3453  0;
3454  ulSet <
3455  m_cUPropSet;
3456  ulSet++)
3457 
3458  {
3459 
3460 if (*
3461  (m_pUPropSet
3462  [ulSet].
3463  pPropSet)
3464  ==
3465  *pPropertySet)
3466 
3467  {
3468 
3470  [m_cPropSetDex]
3471  = ulSet;
3472 
3473 m_cPropSetDex++;
3474 
3475 break;
3476 }
3477 
3478 }
3479 
3480 goto EXIT;
3481 }
3482 
3483 
3484  // Scan
3485  // through
3486  // the
3487  // property
3488  // sets
3489  // looking
3490  // for
3491  // matching
3492  // attributes
3493  for (ulSet =
3494  0;
3495  ulSet <
3496  m_cUPropSet;
3497  ulSet++)
3498 
3499  {
3500 
3501 if
3502  (m_pUPropSet
3503  [ulSet].
3504  pUPropInfo
3505  [0].
3506  dwFlags &
3507  dwFlag)
3508  {
3509 
3511  [m_cPropSetDex]
3512  = ulSet;
3513 
3514 m_cPropSetDex++;
3515 
3516 }
3517 
3518 }
3519 
3520 
3521 EXIT:
3522 return
3523  (m_cPropSetDex)
3524  ? S_OK :
3525  S_FALSE;
3526 
3527 }
3528 
3529  // Retrieve
3530  // the
3531  // property
3532  // id pointer
3533  //
3534  HRESULT
3536  (ULONG
3537  iPropSetDex,
3538  DBPROPID
3539  dwPropertyId,
3540  UPROPINFO **
3541  ppUPropInfo)
3542 
3543  {
3544 
3545  // Scan
3546  // through
3547  // the
3548  // property
3549  // sets
3550  // looking
3551  // for
3552  // matching
3553  // attributes
3554  for (ULONG
3555  ulProps =
3556  0;
3557  ulProps <
3558  m_pUPropSet
3559  [iPropSetDex].
3560  cUPropInfo;
3561  ulProps++)
3562 
3563  {
3564 
3565 if
3566  (m_pUPropSet
3567  [iPropSetDex].
3568  pUPropInfo
3569  [ulProps].
3570  dwPropId ==
3571  dwPropertyId)
3572 
3573  {
3574 
3575 *ppUPropInfo
3576  =
3577  &(m_pUPropSet
3578  [iPropSetDex].
3579  pUPropInfo
3580  [ulProps]);
3581 
3582  // Test to
3583  // see if the
3584  // property
3585  // is
3586  // supported
3587  // for this
3588  // instantiation
3589  return
3590  (TESTBIT
3591  (&
3593  [iPropSetDex
3594  *
3596  ulProps)) ?
3597  S_OK :
3598  S_FALSE;
3599 }
3600 
3601 }
3602 
3603 return
3604  S_FALSE;
3605 }
3606 
3607 HRESULT
3608  FInit (GUID *
3609  pguidSet
3610  =
3611  (GUID
3612  *) &
3613  GUID_NULL)
3614 
3615  {
3616 
3617 CComCritSecLock
3618  <
3619  CComAutoCriticalSection
3620  >
3621  lock
3623 
3624 HRESULT hr;
3625 
3626 
3627 hr =
3629  (&m_cUPropSet,
3630  &m_pUPropSet,
3632  pguidSet);
3633 
3634 if (FAILED
3635  (hr))
3636  return hr;
3637 
3638 ATLASSERT ((m_cUPropSet != 0) && (m_cElemPerSupported != 0));
3640  return E_FAIL;
3641 
3642 ATLTRY (m_rgdwSupported.Allocate (m_cUPropSet * m_cElemPerSupported));
3643 if (m_rgdwSupported == NULL)
3644  return E_OUTOFMEMORY;
3645 
3646 if (FAILED (hr = InitUPropSetsSupported ()))
3647  {
3648 
3650  Free ();
3651 
3652 return hr;
3653 }
3654 
3655 if
3656  (m_cUPropSet)
3657 
3658  {
3659 
3660 ATLTRY
3661  (m_rgiPropSetDex.
3662  Allocate
3663  (m_cUPropSet))
3664 
3665  if
3667  == NULL)
3668  {
3669 
3671  Free ();
3672 
3673 return
3674  E_OUTOFMEMORY;
3675 
3676 }
3677 
3678 }
3679 
3680 return S_OK;
3681 }
3682 
3683 HRESULT
3685  (ULONG
3686  cPropertySets,
3687 
3688 const
3689  DBPROPIDSET
3690  rgPropertySets
3691  [],
3692  ULONG *
3693  pcPropertyInfoSets,
3694 
3695 DBPROPINFOSET
3696  **
3697  prgPropertyInfoSets,
3698 
3699 WCHAR **
3700  ppDescBuffer,
3701  bool
3702  bInitialized
3703  =
3704  true,
3705 
3706 const GUID *
3707  pGuid =
3708  NULL)
3709  {
3710 
3711 CComCritSecLock
3712  <
3713  CComAutoCriticalSection
3714  >
3715  lock
3717 
3718 HRESULT hr =
3719  S_OK;
3720 
3721 ULONG ul,
3722  ulSet, ulNext,
3723  ulEnd;
3724 
3725 ULONG
3726  ulOutIndex;
3727 
3728 ULONG cSets;
3729 
3730 ULONG
3731  cPropInfos;
3732  // ULONG
3733  // ulIndex =
3734  // 0;
3735  ULONG cBuffers
3736  = 0;
3737 
3738 DWORD
3739  dwStatus = 0;
3740 
3741 DBPROPINFO *
3742  pPropInfo =
3743  NULL;
3744 
3745 DBPROPINFO *
3746  pCurPropInfo =
3747  NULL;
3748 
3749 WCHAR *
3750  pDescBuffer =
3751  NULL;
3752 
3753 DBPROPINFOSET
3754  *
3755  pPropInfoSet =
3756  NULL;
3757 
3758 UPROPINFO *
3759  pUPropInfo =
3760  NULL;
3761 
3762 WCHAR
3763  wszBuff[256];
3764 
3765 int cch;
3766 
3767 CAtlArray <
3768  ULONG >
3769  rgInitPropsetIndexes;
3770 
3771 
3772  // If the
3773  // consumer
3774  // does not
3775  // restrict
3776  // the
3777  // property
3778  // sets
3779  // by specify
3780  // an array
3781  // of
3782  // property
3783  // sets and a
3784  // cPropertySets
3785  // greater
3786  // than 0,
3787  // then we
3788  // need to
3789  // make sure
3790  // we
3791  // have some
3792  // to return
3793  if
3794  (cPropertySets
3795  == 0)
3796  {
3797 
3798  // Determine
3799  // the number
3800  // of
3801  // property
3802  // sets
3803  // supported
3804  // In this
3805  // case, it
3806  // usually
3807  // the
3808  // enumerator
3809  // or data
3810  // source
3811  // asking for
3812  //
3813  // DBPROPSET_DBINIT
3814  // information.
3815 
3816 if (pGuid !=
3817  NULL)
3818  {
3819 
3820  // Need to
3821  // determine
3822  // if there
3823  // are any
3824  // UPROPSET_USERINIT
3825  // sets here
3826  // they
3827  // should be
3828  // added to
3829  // DBINIT.
3830  ULONG ulUserInitSets = 0;
3831 for (ULONG l = 0; l < m_cUPropSet; l++)
3832  if (m_pUPropSet[l].dwFlags & UPROPSET_USERINIT)
3833  ulUserInitSets++;
3834 
3835 cSets = 1 + ulUserInitSets; // one
3836  // for
3837  // DBINIT
3838  // which
3839  // is
3840  // required
3841  }
3842 
3843  else
3844 
3845  {
3846 
3847 cSets =
3848  m_cUPropSet;
3849 
3850 }
3851 
3852 }
3853 
3854  else
3855 
3856  {
3857 
3858 cSets = 0;
3859 
3860  // Determine
3861  // number of
3862  // property
3863  // sets
3864  // required
3865  // This is
3866  // only
3867  // required
3868  // when any
3869  // of the
3870  // "special"
3871  // property
3872  // set GUIDs
3873  // were
3874  // specified
3875  for (ulSet =
3876  0;
3877  ulSet <
3878  cPropertySets;
3879  ulSet++)
3880 
3881  {
3882 
3883 if
3885  (&
3886  (rgPropertySets
3887  [ulSet].
3888  guidPropertySet))
3889  ==
3890  S_OK)
3891  cSets
3892  +=
3893  m_cPropSetDex;
3894 
3895  else
3896 
3897 cSets++;
3898 }
3899 
3900 }
3901 
3902 ATLASSERT
3903  (cSets);
3904 
3905  // Allocate
3906  // the
3907  // DBPROPINFOSET
3908  // structures
3909  pPropInfoSet =
3910  (DBPROPINFOSET
3911  *)
3912  CoTaskMemAlloc
3913  (cSets *
3914  sizeof
3915  (DBPROPINFOSET));
3916 
3917 if
3918  (pPropInfoSet
3919  == NULL)
3920  {
3921 
3922 ATLTRACE
3923  (atlTraceDBProvider,
3924  0,
3925  _T
3926  ("Could not allocate DBPROPSET array for GetProperties\n"));
3927 
3928 hr =
3929  E_OUTOFMEMORY;
3930 
3931 goto EXIT;
3932 }
3933 
3934 
3935 memset
3936  (pPropInfoSet,
3937  0,
3938  cSets *
3939  sizeof
3940  (DBPROPINFOSET));
3941 
3942 
3943 ulOutIndex =
3944  0;
3945 
3946 ULONG
3947  ulTempPropsetIndex
3948  = 0;
3949 
3950 ulEnd =
3951  cPropertySets
3952  ==
3953  0 ? cSets :
3954  cPropertySets;
3955 
3956  // Fill in
3957  // the output
3958  // array
3959  for (ulSet =
3960  0;
3961  ulSet <
3962  ulEnd;
3963  ulSet++)
3964 
3965  {
3966 
3967  // Depending
3968  // of if
3969  // Property
3970  // sets are
3971  // specified
3972  // store the
3973  // return
3974  // property
3975  // set.
3976  if
3977  (cPropertySets
3978  == 0)
3979  {
3980 
3981 if (pGuid !=
3982  NULL)
3983  {
3984 
3985  // Need to
3986  // change
3987  // this: set
3988  // the
3989  // guidPropertySet
3990  // to the
3991  // maching
3992  // initialization
3993  // property
3994  // group (not
3995  // DBINITALL).
3996  for (ULONG
3997  ulCurrentInitSet
3998  =
3999  ulTempPropsetIndex;
4000  ulCurrentInitSet
4001  <
4002  m_cUPropSet;
4003  ulCurrentInitSet++)
4004 
4005  {
4006 
4007  // We need to
4008  // locate
4009  // either the
4010  // DBINIT or
4011  // USERINIT
4012  // property
4013  // sets here
4014  // and set
4015  // the
4016  // property
4017  // set index
4018  // up
4019  // correctly.
4020  if
4021  (InlineIsEqualGUID
4022  (*
4023  (m_pUPropSet
4024  [ulCurrentInitSet].
4025  pPropSet),
4026  DBPROPSET_DBINIT)
4027  ||
4028 
4029 (m_pUPropSet
4030  [ulCurrentInitSet].
4031  dwFlags &
4033 
4034  {
4035 
4036 rgInitPropsetIndexes.
4037  Add
4038  (ulCurrentInitSet);
4039 
4040 ulTempPropsetIndex
4041  =
4042  ulCurrentInitSet
4043  + 1;
4044  // ulIndex =
4045  // ulCurrentInitSet;
4046  // pPropInfoSet[ulSet].guidPropertySet
4047  // = *pGuid;
4048  pPropInfoSet[ulSet].guidPropertySet = *(m_pUPropSet[ulCurrentInitSet].pPropSet);
4049 GetPropertySetIndex (&pPropInfoSet[ulSet].guidPropertySet); // Need
4050  // to
4051  // set
4052  // the
4053  // m_cPropSetDex
4054  // variable
4055  break;
4056 }
4057 
4058 }
4059 
4060  // if
4061  // (ulCurrentInitSet
4062  // ==
4063  // m_cUPropSet)
4064  // {
4065  // ulIndex =
4066  // 0;
4067  // }
4068 
4069 }
4070 
4071  else
4072 
4073  {
4074 
4075 pPropInfoSet
4076  [ulSet].
4077  guidPropertySet
4078  =
4079  *(m_pUPropSet
4080  [ulSet].
4081  pPropSet);
4082 
4083 }
4084 
4085 }
4086 
4087  else
4088 
4089  {
4090 
4091 GUID const
4092  &guidSet =
4093  rgPropertySets
4094  [ulSet].
4095  guidPropertySet;
4096 
4097 if ((InlineIsEqualGUID (guidSet, DBPROPSET_DATASOURCEALL) ||
4098 InlineIsEqualGUID (guidSet, DBPROPSET_DATASOURCEINFOALL) ||
4099 InlineIsEqualGUID (guidSet, DBPROPSET_DBINITALL) ||
4100 InlineIsEqualGUID (guidSet, DBPROPSET_SESSIONALL) ||
4101 InlineIsEqualGUID (guidSet, DBPROPSET_COLUMNALL) ||
4102 InlineIsEqualGUID (guidSet, DBPROPSET_CONSTRAINTALL) ||
4103 InlineIsEqualGUID (guidSet, DBPROPSET_INDEXALL) ||
4104 InlineIsEqualGUID (guidSet, DBPROPSET_TABLEALL) ||
4105 InlineIsEqualGUID (guidSet, DBPROPSET_TRUSTEEALL) ||
4106 InlineIsEqualGUID (guidSet, DBPROPSET_VIEWALL) ||
4107 InlineIsEqualGUID (guidSet, DBPROPSET_ROWSETALL)) &&
4108 GetPropertySetIndex (&guidSet) == S_OK)
4109  {
4110 
4111 for (ul = 0;
4112  ul <
4113  m_cPropSetDex;
4114  ul++,
4115  ulOutIndex++)
4116 
4117  {
4118 
4119 pPropInfoSet
4120  [ulOutIndex].
4121  guidPropertySet
4122  =
4123  *(m_pUPropSet
4125  [ul]].
4126  pPropSet);
4127 // pPropInfoSet[ulOutIndex].guidPropertySet = rgPropertySets[ulSet].guidPropertySet;
4128  pPropInfoSet
4129  [ulOutIndex].
4130  cPropertyInfos
4131  = 0;
4132 }
4133 
4134 }
4135 
4136  else
4137 
4138  {
4139 
4140  // Handle
4141  // non-category
4142  // property
4143  // sets
4144  // Handle
4145  // unknown
4146  // property
4147  // sets
4148  pPropInfoSet
4149  [ulOutIndex].
4150  guidPropertySet
4151  = guidSet;
4152 
4153 pPropInfoSet
4154  [ulOutIndex].
4155  cPropertyInfos
4156  =
4157  rgPropertySets
4158  [ulSet].
4159  cPropertyIDs;
4160 
4161 ulOutIndex++;
4162 
4163 }
4164 
4165 }
4166 
4167 }
4168 
4169 
4170  // Allocate a
4171  // Description
4172  // Buffer if
4173  // needed
4174  if
4175  (ppDescBuffer)
4176 
4177  {
4178 
4179 cBuffers =
4181  (cSets,
4182  pPropInfoSet);
4183 
4184 if (cBuffers
4185  != 0)
4186  {
4187 
4188 pDescBuffer =
4189  (WCHAR *)
4190  CoTaskMemAlloc
4191  (cBuffers *
4193  *
4194  sizeof
4195  (WCHAR));
4196 
4197 if
4198  (pDescBuffer
4199  == NULL)
4200  {
4201 
4202 hr =
4203  E_OUTOFMEMORY;
4204 
4205 goto EXIT;
4206 }
4207 
4208 *ppDescBuffer
4209  = pDescBuffer;
4210 
4211 memset
4212  (pDescBuffer,
4213  0,
4214  (cBuffers *
4216  *
4217  sizeof
4218  (WCHAR)));
4219 
4220 }
4221 
4222 }
4223 
4224 
4225  // Process
4226  // requested
4227  // or derived
4228  // Property
4229  // sets
4230  dwStatus = 0;
4231 
4232 for (ulSet =
4233  0;
4234  ulSet <
4235  cSets;
4236  ulSet++)
4237 
4238  {
4239 
4240 ulNext = 0;
4241 
4242 cPropInfos =
4243  0;
4244 
4245 pPropInfo =
4246  NULL;
4247 
4248 dwStatus &=
4250  |
4252 
4253 
4254  // Calculate
4255  // the number
4256  // of
4257  // property
4258  // nodes
4259  // needed for
4260  // this
4261  // property
4262  // set.
4263  if
4264  (cPropertySets
4265  == 0)
4266  {
4267 
4268 ULONG
4269  ulTempSet;
4270 
4271 if (pGuid !=
4272  NULL)
4273  {
4274 
4275 ATLASSERT (ulSet < rgInitPropsetIndexes.GetCount ());
4276 ulTempSet = rgInitPropsetIndexes[ulSet]; // ulIndex;
4277  }
4278 
4279  else
4280 
4281 ulTempSet =
4282  ulSet;
4283 
4284 
4285 cPropInfos =
4286  m_pUPropSet
4287  [ulTempSet].
4288  cUPropInfo;
4289 
4290 dwStatus |=
4292 
4294  [0] =
4295  ulTempSet;
4296 
4298  = 1;
4299 
4301  (*m_pUPropSet
4302  [ulTempSet].
4303  pPropSet,
4304  dwStatus);
4305 }
4306 
4307  else
4308 
4309  {
4310 
4311  // If the
4312  // count of
4313  // PROPIDs is
4314  // 0 (NOTE:
4315  // the above
4316  // routine
4317  // already
4318  // determined
4319  // if it
4320  // belonged
4321  // to a
4322  // category
4323  // and if so
4324  // set the
4325  // count of
4326  // properties
4327  // to 0 for
4328  // each
4329  // propset in
4330  // that
4331  // category.
4332  if
4333  (pPropInfoSet
4334  [ulSet].
4335  cPropertyInfos
4336  == 0)
4337  {
4338 
4339 dwStatus |=
4341 
4342  // We have to
4343  // determine
4344  // if the
4345  // property
4346  // set is
4347  // supported
4348  // and if so
4349  // the count
4350  // of
4351  // properties
4352  // in the
4353  // set.
4354  if ((GetPropertySetIndex (&(pPropInfoSet[ulSet].guidPropertySet)) == S_FALSE)
4355  ||(!bInitialized &&
4356 !(InlineIsEqualGUID (pPropInfoSet[ulSet].guidPropertySet, DBPROPSET_DBINIT)) &&
4357 !(InlineIsEqualGUID (pPropInfoSet[ulSet].guidPropertySet, DBPROPSET_DBINITALL))))
4358  {
4359 
4360 dwStatus |=
4362 
4363 dwStatus |=
4365 
4367  (pPropInfoSet
4368  [ulSet].
4369  guidPropertySet,
4370  dwStatus);
4371 
4372 goto
4373  NEXT_SET;
4374 }
4375 
4376  else
4377 
4378  {
4379 
4380 ATLASSERT
4381  (m_cPropSetDex
4382  == 1);
4383 
4384 cPropInfos +=
4385  m_pUPropSet
4387  [0]].
4388  cUPropInfo;
4389 
4391  (pPropInfoSet
4392  [ulSet].
4393  guidPropertySet,
4394  dwStatus);
4395 }
4396 
4397 // else
4398 // {
4399 // // Not Supported
4400 // dwStatus |= GETPROPINFO_ERRORSOCCURRED;
4401 // goto NEXT_SET;
4402 // }
4403  }
4404 
4405  else
4406 
4407  {
4408 
4409  // We also
4410  // handle the
4411  // case here
4412  // where the
4413  // user has
4414  // requested
4415  // a
4416  // non-initialization
4417  // group
4418  // property
4419  // info set
4420  // while the
4421  // provider
4422  // is not
4423  // initialized.
4424  // In this
4425  // case,
4426  // properties
4427  // should
4428  // not be
4429  // set.
4430  cPropInfos =
4431  pPropInfoSet
4432  [ulSet].
4433  cPropertyInfos;
4434 
4435 if ((GetPropertySetIndex (&(pPropInfoSet[ulSet].guidPropertySet)) == S_FALSE)
4436  ||(!bInitialized &&
4437 !(InlineIsEqualGUID (pPropInfoSet[ulSet].guidPropertySet, DBPROPSET_DBINIT)) &&
4438 !(InlineIsEqualGUID (pPropInfoSet[ulSet].guidPropertySet, DBPROPSET_DBINITALL))))
4439  {
4440 
4441 dwStatus |=
4443 
4444 dwStatus |=
4446 
4448  (pPropInfoSet
4449  [ulSet].
4450  guidPropertySet,
4451  dwStatus);
4452 }
4453 
4454 }
4455 
4456 }
4457 
4458 
4459 
4460  // Allocate
4461  // DBPROP
4462  // array
4463  ATLASSERT
4464  (cPropInfos !=
4465  0);
4466 
4467 pPropInfo =
4468  (DBPROPINFO *)
4469  CoTaskMemAlloc
4470  (cPropInfos *
4471  sizeof
4472  (DBPROPINFO));
4473 
4474 if
4475  (pPropInfo)
4476  {
4477 
4478  // Initialize
4479  // Buffer
4480  memset
4481  (pPropInfo, 0,
4482  cPropInfos *
4483  sizeof
4484  (DBPROPINFO));
4485 
4486 for (ULONG
4487  ulProp =
4488  0;
4489  ulProp <
4490  cPropInfos;
4491  ulProp++)
4492 
4493  {
4494 
4495 VariantInit
4496  (&
4497  (pPropInfo
4498  [ulProp].
4499  vValues));
4500 
4501 if (dwStatus
4502  &
4504 
4505  {
4506 
4507  // Not
4508  // supported,
4509  // thus we
4510  // need to
4511  // mark all
4512  // as
4513  // NOT_SUPPORTED
4514  pPropInfo
4515  [ulProp].
4516  dwPropertyID =
4517  rgPropertySets
4518  [ulSet].
4519  rgPropertyIDs
4520  [ulProp];
4521 
4522 pPropInfo
4523  [ulProp].
4524  dwFlags =
4525  DBPROPFLAGS_NOTSUPPORTED;
4526 
4527 dwStatus |=
4529 
4531  (pPropInfo
4532  [ulProp].
4533  dwPropertyID,
4534  pPropInfo
4535  [ulProp].
4536  dwFlags);
4537 }
4538 
4539 }
4540 
4541  // Make sure
4542  // we support
4543  // the
4544  // property
4545  // set
4546  if (dwStatus &
4548 
4549  {
4550 
4551 ulNext =
4552  cPropInfos;
4553 
4554 goto
4555  NEXT_SET;
4556 }
4557 
4558 
4559  // Retrieve
4560  // the
4561  // property
4562  // information
4563  // for this
4564  // property
4565  // set
4566  for (ul = 0;
4567  ul <
4568  m_cPropSetDex;
4569  ul++)
4570  {
4571 
4572 pUPropInfo =
4573  (m_pUPropSet
4575  [ul]].
4576  pUPropInfo);
4577 
4578 ATLASSERT
4579  (pUPropInfo);
4580 
4581 
4582  // Retrieve
4583  // current
4584  // value of
4585  // properties
4586  if (dwStatus &
4588 
4589  {
4590 
4591 for (ulProp =
4592  0;
4593  ulProp <
4594  m_pUPropSet
4596  [ul]].
4597  cUPropInfo;
4598  ulProp++)
4599 
4600  {
4601 
4602  // Verify
4603  // property
4604  // is
4605  // supported,
4606  // if not do
4607  // not return
4608  //
4609  if (!TESTBIT
4610  (&
4613  [ul] *
4615  ulProp))
4616 
4617  continue;
4618 
4619 
4620 pCurPropInfo
4621  =
4622  &(pPropInfo
4623  [ulNext]);
4624 
4625 
4626  // If the
4627  // ppDescBuffer
4628  // pointer
4629  // was not
4630  // NULL,
4631  // then
4632  // we need
4633  // supply
4634  // description
4635  // of the
4636  // properties
4637  if
4638  (ppDescBuffer)
4639 
4640  {
4641 
4642  // Set Buffer
4643  // pointer
4644  pCurPropInfo->
4645  pwszDescription
4646  = pDescBuffer;
4647 
4648 
4649  // Load the
4650  // string
4651  // into temp
4652  // buffer
4653  cch =
4655  (pUPropInfo
4656  [ulProp].
4657  ulIDS,
4658  wszBuff,
4659  (sizeof
4660  (wszBuff) /
4661  sizeof
4662  (*wszBuff)));
4663 
4664 if (cch)
4665  {
4666 
4667  // Adjust for
4668  // '\0'
4669  cch++;
4670 
4671  // Transfer
4672  // to
4673  // official
4674  // buffer if
4675  // room
4676  memcpy
4677  (pDescBuffer,
4678  wszBuff,
4679  cch *
4680  sizeof
4681  (WCHAR));
4682 
4683 pDescBuffer
4684  += cch;
4685 }
4686 
4687  else
4688 
4689  {
4690 
4691 wcscpy
4692  (pDescBuffer,
4693  L"UNKNOWN");
4694 
4695 pDescBuffer
4696  +=
4697  (wcslen
4698  (L"UNKNOWN")
4699  + 1);
4700 
4702  (pCurPropInfo->
4703  dwPropertyID,
4704  ATLDB_NO_STRING);
4705 
4706 }
4707 
4708 }
4709 
4710 
4711 pCurPropInfo->
4712  dwPropertyID =
4713  pUPropInfo
4714  [ulProp].
4715  dwPropId;
4716 
4717  // Strip out
4718  // any user
4719  // defined
4720  // flags that
4721  // may be
4722  // around.
4723  // Note,
4724  // this isn't
4725  // a
4726  // full-proof
4727  // thing
4728  // because
4729  // properties
4730  // change.
4731  // It
4732  // won't work
4733  // in OLE DB
4734  // 2.5 if
4735  // someone
4736  // does a
4737  // property
4738  // like
4739  // 0x40000
4740  DWORD dwFlags
4741  =
4742  pUPropInfo
4743  [ulProp].
4744  dwFlags &
4745  0xfffff;
4746 
4747 
4748 pCurPropInfo->
4749  dwFlags =
4750  dwFlags;
4751 
4752 pCurPropInfo->
4753  vtType =
4754  pUPropInfo
4755  [ulProp].
4756  VarType;
4757 
4758 pCurPropInfo->
4759  vValues.vt =
4760  VT_EMPTY;
4761 
4762 
4763 dwStatus |=
4765 
4766  // Increment
4767  // to next
4768  // available
4769  // buffer
4770  ulNext++;
4771 
4773  (pCurPropInfo->
4774  dwPropertyID,
4775  pCurPropInfo->
4776  dwFlags);
4777 }
4778 
4779 }
4780 
4781  else
4782 
4783  {
4784 
4785 ATLASSERT
4786  (m_cPropSetDex
4787  == 1);
4788 
4789 ULONG
4790  cIterations =
4791  ((cPropInfos >
4792  cBuffers)
4793  &&
4794  (ppDescBuffer))
4795  ? cBuffers :
4796  cPropInfos;
4797 
4798 
4799 for (ulProp
4800  = 0;
4801  ulProp
4802  <
4803  cIterations;
4804  ulProp++,
4805  ulNext++)
4806 
4807  {
4808 
4809 pCurPropInfo
4810  =
4811  &(pPropInfo
4812  [ulNext]);
4813 
4814 
4815  // Process
4816  // Properties
4817  // based on
4818  // Restriction
4819  // array.
4820  pCurPropInfo->
4821  dwPropertyID =
4822  rgPropertySets
4823  [ulSet].
4824  rgPropertyIDs
4825  [ulProp];
4826 
4827 
4828 if
4831  [ul],
4832  pCurPropInfo->
4833  dwPropertyID,
4834  &pUPropInfo)
4835 
4836  == S_OK)
4837  {
4838 
4839  // If the
4840  // ppDescBuffer
4841  // pointer
4842  // was not
4843  // NULL,
4844  // then
4845  // we need
4846  // supply
4847  // description
4848  // of the
4849  // properties
4850  if
4851  (ppDescBuffer)
4852 
4853  {
4854 
4855  // Set Buffer
4856  // pointer
4857  pCurPropInfo->
4858  pwszDescription
4859  = pDescBuffer;
4860 
4861 
4862  // Load the
4863  // string
4864  // into temp
4865  // buffer
4866  cch =
4868  (pUPropInfo->
4869  ulIDS,
4870  wszBuff,
4871  (sizeof
4872  (wszBuff) /
4873  sizeof
4874  (*wszBuff)));
4875 
4876 if (cch)
4877  {
4878 
4879  // Adjust for
4880  // '\0'
4881  cch++;
4882 
4883  // Transfer
4884  // to
4885  // official
4886  // buffer if
4887  // room
4888  memcpy
4889  (pDescBuffer,
4890  wszBuff,
4891  cch *
4892  sizeof
4893  (WCHAR));
4894 
4895 pDescBuffer
4896  += cch;
4897 }
4898 
4899  else
4900 
4901  {
4902 
4903 wcscpy
4904  (pDescBuffer,
4905  L"UNKNOWN");
4906 
4907 pDescBuffer
4908  +=
4909  (wcslen
4910  (L"UNKNOWN")
4911  + 1);
4912 
4914  (pCurPropInfo->
4915  dwPropertyID,
4916  ATLDB_NO_STRING);
4917 
4918 }
4919 
4920 }
4921 
4922 
4923 pCurPropInfo->
4924  dwPropertyID =
4925  pUPropInfo->
4926  dwPropId;
4927 
4928  // Strip out
4929  // any user
4930  // defined
4931  // flags that
4932  // may be
4933  // around.
4934  // Note,
4935  // this isn't
4936  // a
4937  // full-proof
4938  // thing
4939  // because
4940  // properties
4941  // change.
4942  // It
4943  // won't work
4944  // in OLE DB
4945  // 2.5 if
4946  // someone
4947  // does a
4948  // property
4949  // like
4950  // 0x40000
4951  DWORD dwFlags
4952  =
4953  pUPropInfo->
4954  dwFlags &
4955  0xfffff;
4956 
4957 
4958 pCurPropInfo->
4959  dwFlags =
4960  dwFlags;
4961 
4962 pCurPropInfo->
4963  vtType =
4964  pUPropInfo->
4965  VarType;
4966 
4967 
4968 dwStatus |=
4970 
4971 }
4972 
4973  else
4974 
4975  {
4976 
4977  // Not
4978  // Supported
4979  pCurPropInfo->
4980  dwFlags =
4981  DBPROPFLAGS_NOTSUPPORTED;
4982 
4983 dwStatus |=
4985 
4986 }
4987 
4989  (pCurPropInfo->
4990  dwPropertyID,
4991  pCurPropInfo->
4992  dwFlags);
4993 }
4994 
4995 }
4996 
4997 }
4998 
4999 }
5000 
5001  else
5002 
5003  {
5004 
5005 hr =
5006  E_OUTOFMEMORY;
5007 
5008 goto EXIT;
5009 }
5010 
5011 
5012 NEXT_SET:
5013 pPropInfoSet
5014  [ulSet].
5015  cPropertyInfos
5016  = ulNext;
5017 
5018 pPropInfoSet
5019  [ulSet].
5020  rgPropertyInfos
5021  = pPropInfo;
5022 
5023 }
5024 
5025 
5026  // Success,
5027  // set return
5028  // values
5029  *pcPropertyInfoSets
5030  = cSets;
5031 
5032 *prgPropertyInfoSets
5033  =
5034  pPropInfoSet;
5035 
5036 
5037  // At least
5038  // one propid
5039  // was marked
5040  // as not
5041  // S_OK
5042  if (dwStatus &
5044 
5045  {
5046 
5047  // If at
5048  // least 1
5049  // property
5050  // was set
5051  if (dwStatus &
5053 
5054  return
5055  DB_S_ERRORSOCCURRED;
5056 
5057  else
5058 
5059  {
5060 
5061  // Do not
5062  // free any
5063  // of the
5064  // rgPropertyInfoSets,
5065  // but
5066  // do free
5067  // the
5068  // ppDescBuffer
5069  if
5070  (pDescBuffer)
5071 
5072  {
5073 
5074 ATLASSERT
5075  (ppDescBuffer);
5076 
5077 CoTaskMemFree
5078  (pDescBuffer);
5079 
5080 *ppDescBuffer
5081  = NULL;
5082 }
5083 
5084 return
5085  DB_E_ERRORSOCCURRED;
5086 
5087 }
5088 
5089 }
5090 
5091 
5092 return S_OK;
5093 EXIT:
5094  // Check if
5095  // failure
5096  // and clean
5097  // up any
5098  // allocated
5099  // memory
5100  if (FAILED
5101  (hr)
5102  &&
5103 (hr !=
5104  DB_E_ERRORSOCCURRED))
5105 
5106  {
5107 
5108  // Free
5109  // Description
5110  // Buffer
5111  if
5112  (pDescBuffer)
5113 
5114  {
5115 
5116 ATLASSERT
5117  (ppDescBuffer);
5118 
5119 
5120 CoTaskMemFree
5121  (pDescBuffer);
5122 
5123 *ppDescBuffer
5124  = NULL;
5125 }
5126 
5127 
5128 if
5129  (pPropInfoSet)
5130 
5131  {
5132 
5133  // Loop
5134  // through
5135  // Property
5136  // Sets
5137  for (ulSet =
5138  0;
5139  ulSet <
5140  cSets;
5141  ulSet++)
5142 
5143  CoTaskMemFree
5144  (pPropInfoSet
5145  [ulSet].
5146  rgPropertyInfos);
5147 
5148 CoTaskMemFree
5149  (pPropInfoSet);
5150 
5151 }
5152 
5153 }
5154 
5155 
5156 return hr;
5157 }
5158 
5159 
5160 CComAutoCriticalSection m_oCriticalSection; // critical
5161  // section
5162  // to
5163  // synchronize
5164  // access
5165  // to
5166  // the
5167  // class
5168  ULONG m_cUPropSet; // count
5169  // of
5170  // UPropSet
5171  // items
5172  UPROPSET * m_pUPropSet; // Pointer
5173  // to
5174  // UPropset
5175  // items
5176  ULONG m_cPropSetDex; // count
5177  // of
5178  // UPropSet
5179  // Indexes
5180  CAutoVectorPtr < ULONG > m_rgiPropSetDex; // array
5181  // of
5182  // UPropSet
5183  // Index
5184  // values
5185  ULONG m_cElemPerSupported; // number
5186  // of
5187  // DWORDS
5188  // per
5189  // UPropSet
5190  // to
5191  // indicate
5192  // supported
5193  // UPropIds
5194  CAutoVectorPtr < DWORD > m_rgdwSupported; // array
5195  // of
5196  // DWORDs
5197  // indicating
5198  // supported
5199  // UPropIds
5200  //
5201 
5202 enum
5204 
5205  {
5206 
5208  = 0x1,
5209 
5211  = 0x2,
5212 
5214  = 0x4
5215  };
5216 
5217 
5218 HRESULT
5220  (ULONG *
5221  pcUPropSet,
5222  UPROPSET **
5223  ppUPropSet,
5224  ULONG *
5225  pcElemPerSupported,
5226  GUID *
5227  pguid)
5228  {
5229 
5230 ATLASSERT
5231  (pcUPropSet
5232  &&
5233  ppUPropSet);
5234 
5235 CoTaskMemFree
5236  (*ppUPropSet);
5237 
5238 *ppUPropSet =
5239  NULL;
5240 
5241 int cSets =
5242  (int)
5243  (ULONG_PTR)
5244  T::
5245  _GetPropSet
5246  (NULL,
5247  pcElemPerSupported);
5248 
5249 UPROPSET *
5250  pSet =
5251  (UPROPSET *)
5252  CoTaskMemAlloc
5253  (sizeof
5254  (UPROPSET) *
5255  cSets);
5256 
5257 if (pSet ==
5258  NULL)
5259  return
5260  E_OUTOFMEMORY;
5261 
5262 *ppUPropSet =
5263  T::
5264  _GetPropSet
5265  (pcUPropSet,
5266  pcElemPerSupported,
5267  pSet, pguid);
5268 
5269 return S_OK;
5270 
5271 }
5272 
5274  HRESULT
5276  ()
5277  {
5278 
5279 ULONG
5280  cPropSet =
5281  0,
5282  cElemsPerSupported
5283  = 0;
5284 
5285 int cSets =
5286  (int)
5287  (ULONG_PTR)
5288  T::
5289  _GetPropSet
5290  (NULL,
5291  &cElemsPerSupported);
5292 
5293 UPROPSET *
5294  pSet =
5295  (UPROPSET *)
5296  CoTaskMemAlloc
5297  (sizeof
5298  (UPROPSET) *
5299  cSets);
5300 
5301 if (pSet ==
5302  NULL)
5303  return
5304  E_OUTOFMEMORY;
5305 
5306 pSet =
5307  T::
5308  _GetPropSet
5309  (&cPropSet,
5310  &cElemsPerSupported,
5311  pSet);
5312 
5313 memset
5314  (m_rgdwSupported,
5315  0xFFFF,
5316  cPropSet *
5317  cElemsPerSupported
5318  *
5319  sizeof
5320  (DWORD));
5321 
5322 CoTaskMemFree
5323  (pSet);
5324 
5325 return S_OK;
5326 
5327 }
5328 
5329  // Load a
5330  // localized
5331  // description
5332  int
5334  (ULONG ids,
5335  PWSTR
5336  pwszBuff,
5337  ULONG
5338  cchBuff)
5339  {
5340 
5341 USES_CONVERSION;
5342 
5343 CTempBuffer <
5344  TCHAR >
5345  tmpBuffer;
5346 
5347 TCHAR *
5348  pszBuf =
5349  tmpBuffer.
5350  Allocate
5351  (cchBuff);
5352 
5353 if (pszBuf ==
5354  NULL)
5355  return 0;
5356 
5357 int nTemp =
5358  LoadString
5359  (_AtlBaseModule.
5360  GetResourceInstance
5361  (), ids,
5362  pszBuf,
5363  cchBuff);
5364 
5365 if (nTemp !=
5366  0)
5367  {
5368 
5369 wcscpy
5370  (pwszBuff,
5371  T2W
5372  (pszBuf));
5373 }
5374 
5375 return nTemp;
5376 }
5377 
5378 };
5379 
5380 
5381 class ATL_NO_VTABLE CUtlPropsBase: public
5382  CBitFieldOps,
5383  public
5384  CDBIDOps
5385  {
5386 
5387 public:
5388 
5389 CComAutoCriticalSection m_oCriticalSection; // critical
5390  // section
5391  // to
5392  // synchronize
5393  // access
5394  // to
5395  // the
5396  // class
5397  ULONG m_cUPropSet; // count
5398  // of
5399  // UPropSet
5400  // items
5401  UPROPSET * m_pUPropSet; // Pointer
5402  // to
5403  // UPropset
5404  // items
5405  CAutoVectorPtr < UPROP > m_pUProp;
5406 ULONG m_cUPropSetHidden; // Count
5407  // of
5408  // Hidden
5409  // items
5410  DWORD m_dwFlags; // Configuration
5411  // flags
5412  ULONG m_cPropSetDex; // count
5413  // of
5414  // UPropSet
5415  // Indexes
5416  CAutoVectorPtr < ULONG > m_rgiPropSetDex; // pointer
5417  // to
5418  // Array
5419  // of
5420  // UPropSet
5421  // Index
5422  // values
5423  ULONG m_cElemPerSupported; // number
5424  // of
5425  // DWORDS
5426  // per
5427  // UPropSet
5428  // to
5429  // indicate
5430  // supported
5431  // UPropIds
5432  CAutoVectorPtr < DWORD > m_rgdwSupported; // pointer
5433  // to
5434  // array
5435  // of
5436  // DWORDs
5437  // indicating
5438  // supported
5439  // UPropIds
5440  //
5441  CAutoVectorPtr < DWORD > m_rgdwPropsInError; // pointer
5442  // to
5443  // array
5444  // of
5445  // DWORDs
5446  // indicating
5447  // if
5448  // property
5449  // is
5450  // in
5451  // error
5452 
5453 enum
5455 
5456  {
5457 
5458 UPROPSET_HIDDEN
5459  = 0x1,
5460 
5461 UPROPSET_PASSTHROUGH
5462  = 0x2,
5463 
5464 UPROPSET_USERINIT
5465  = 0x4
5466  };
5467 
5468 enum
5469  EnumGetProp
5470  {
5471 
5472 GETPROP_ALLPROPIDS
5473  = 0x0001,
5474 
5475 GETPROP_NOTSUPPORTED
5476  = 0x0002,
5477 
5478 GETPROP_ERRORSOCCURRED
5479  = 0x0004,
5480 
5481 GETPROP_VALIDPROP
5482  = 0x0008,
5483 
5484 GETPROP_PROPSINERROR
5485  = 0x0010
5486  };
5487 
5488 
5489 enum
5490  EnumSetProp
5491  {
5492 
5493 SETPROP_BADOPTION
5494  = 0x0001,
5495 
5496 SETPROP_NOTSUPPORTED
5497  = 0x0002,
5498 
5499 SETPROP_VALIDPROP
5500  = 0x0004,
5501 
5502 SETPROP_ERRORS
5503  = 0x0008,
5504 
5505 SETPROP_COLUMN_LEVEL
5506  = 0x0010,
5507 
5508 SETPROP_WAS_REQUIRED
5509  = 0x0020
5510  };
5511 
5512 
5513 HRESULT
5514  SetPassThrough
5515  (const
5516  DBPROPSET *
5517  pPropSet)
5518  {
5519 
5520 ATLASSERT
5521  (pPropSet);
5522 
5523 
5524 DBPROP *
5525  pProp =
5526  pPropSet->
5527  rgProperties;
5528 
5529 
5530  // Default
5531  // implementation
5532  // just sets
5533  // all
5534  // properties
5535  // as
5536  // NOTSUPPORTED
5537  for (ULONG ul
5538  = 0;
5539  ul <
5540  pPropSet->
5541  cProperties;
5542  ul++,
5543  pProp++)
5544 
5545  pProp->
5546  dwStatus =
5547  DBPROPSTATUS_NOTSUPPORTED;
5548 
5549 
5550 return
5551  DB_E_ERRORSOCCURRED;
5552 
5553 }
5554 
5555 
5556 HRESULT
5557  GetIndexofPropIdinPropSet
5558  (ULONG
5559  iCurSet,
5560  DBPROPID
5561  dwPropertyId,
5562  ULONG *
5563  piCurPropId)
5564 
5565  {
5566 
5567 ATLASSERT
5568  (piCurPropId);
5569 
5570 UPROPINFO *
5571  pUPropInfo =
5572  m_pUPropSet
5573  [iCurSet].
5574  pUPropInfo;
5575 
5576 for (ULONG ul
5577  = 0;
5578  ul <
5579  m_pUPropSet
5580  [iCurSet].
5581  cUPropInfo;
5582  ul++)
5583  {
5584 
5585 if
5586  (dwPropertyId
5587  ==
5588  pUPropInfo
5589  [ul].
5590  dwPropId)
5591  {
5592 
5593 *piCurPropId
5594  = ul;
5595  // Test to
5596  // see if the
5597  // property
5598  // is
5599  // supported
5600  // for this
5601  // instantiation
5602  return
5603  (TESTBIT
5604  (&
5605  (m_rgdwSupported
5606  [iCurSet *
5607  m_cElemPerSupported]),
5608  ul)) ? S_OK
5609  : S_FALSE;
5610 }
5611 
5612 }
5613 
5614 
5615 return
5616  S_FALSE;
5617 }
5618 
5619 
5620 virtual HRESULT IsValidValue (ULONG /* iCurSet
5621  */
5622  ,
5623  DBPROP
5624  *
5625  pDBProp)
5626 
5627  {
5628 
5629 ATLASSERT
5630  (pDBProp !=
5631  NULL);
5632 
5633 CComVariant
5634  var =
5635  pDBProp->
5636  vValue;
5637 
5638 if (var.vt ==
5639  VT_BOOL)
5640 
5641  {
5642 
5643 if (var.
5644  boolVal
5645  !=
5647  && var.
5648  boolVal
5649  !=
5651 
5652  return
5653  S_FALSE;
5654 }
5655 
5656 
5657 return S_OK;
5658 }
5659 
5660 
5661 virtual
5662  HRESULT
5663  OnInterfaceRequested
5664  (REFIID riid)
5665 
5666  {
5667 
5668  // This
5669  // function
5670  // exists as
5671  // part of
5672  // the change
5673  // in the OLE
5674  // DB spec.
5675  // If
5676  // a consumer
5677  // opens an
5678  // object and
5679  // requests
5680  // an
5681  // optional
5682  // interface,
5683  // the
5684  // provider
5685  // should
5686  // automatically
5687  // set the
5688  // property
5689  // representating
5690  // that
5691  // interface
5692  // to true.
5693  CDBPropSet
5694  propset
5695  (DBPROPSET_ROWSET);
5696 
5697 const GUID *
5698  ppGuid[1];
5699 
5700 ppGuid[0] =
5702 
5703 
5704 if
5705  (InlineIsEqualGUID
5706  (riid,
5707  __uuidof
5708  (IRowsetChange)))
5709 
5710  propset.
5711  AddProperty
5712  (DBPROP_IRowsetChange,
5713  true);
5714  else
5715  if
5716  (InlineIsEqualGUID
5717  (riid,
5718  __uuidof
5719  (IRowsetUpdate)))
5720 
5721  propset.
5722  AddProperty
5723  (DBPROP_IRowsetUpdate,
5724  true);
5725  else
5726  if
5727  (InlineIsEqualGUID
5728  (riid,
5729  __uuidof
5730  (IRowsetLocate)))
5731 
5732  propset.
5733  AddProperty
5734  (DBPROP_IRowsetLocate,
5735  true);
5736  else
5737  if
5738  (InlineIsEqualGUID
5739  (riid,
5740  __uuidof
5741  (IConnectionPointContainer)))
5742 
5743  propset.
5744  AddProperty
5745  (DBPROP_IConnectionPointContainer,
5746  true);
5747  else
5748  if
5749  (InlineIsEqualGUID
5750  (riid,
5751  __uuidof
5752  (IRowsetScroll)))
5753 
5754  propset.
5755  AddProperty
5756  (DBPROP_IRowsetScroll,
5757  true);
5758 
5759 
5760 if (propset.
5761  cProperties
5762  >
5763  0)
5764  return
5765  SetProperties
5766  (0, 1,
5767  &propset, 1,
5768  ppGuid);
5769 
5770 
5771 return S_OK;
5772 
5773 }
5774 
5775 
5776 virtual HRESULT OnPropertyChanged (ULONG /* iCurSet
5777  */
5778  , DBPROP *
5779  /* pDBProp
5780  */
5781  )
5782  = 0;
5783 
5784 HRESULT
5785  SetProperty
5786  (ULONG
5787  iCurSet,
5788  ULONG
5789  iCurProp,
5790  DBPROP *
5791  pDBProp)
5792  {
5793 
5794 HRESULT hr =
5795  S_OK;
5796 
5797 UPROP *
5798  pUProp;
5799 
5800 UPROPVAL *
5801  pUPropVal;
5802 
5803 UPROPINFO *
5804  pUPropInfo;
5805 
5806 ULONG iUProp;
5807 
5808 
5809 ATLASSERT
5810  (pDBProp);
5811 
5812  // Set
5813  // pointer to
5814  // correct
5815  // set
5816  pUProp =
5817  &(m_pUProp
5818  [iCurSet]);
5819 
5820 ATLASSERT
5821  (pUProp);
5822 
5823 
5824 pUPropInfo =
5825  &(m_pUPropSet
5826  [iCurSet].
5827  pUPropInfo
5828  [iCurProp]);
5829 
5830 ATLASSERT
5831  (pUPropInfo);
5832 
5833 
5834  // Determine
5835  // the index
5836  // within
5837  // m_pUProp
5838  for (iUProp =
5839  0;
5840  iUProp <
5841  pUProp->
5842  cPropIds;
5843  iUProp++)
5844 
5845  {
5846 
5847 if ((pUProp->
5848  rgpUPropInfo
5849  [iUProp])->
5850  dwPropId
5851  ==
5852  pDBProp->
5853  dwPropertyID)
5854 
5855  break;
5856 }
5857 
5858 
5859 if (iUProp
5860  >=
5861  pUProp->
5862  cPropIds)
5863 
5864  {
5865 
5866 ATLASSERT
5867  (!"Should have found index of property to set");
5868 
5869 hr = E_FAIL;
5870 
5871 pDBProp->
5872  dwStatus =
5873  DBPROPSTATUS_NOTSUPPORTED;
5874 
5875 goto EXIT;
5876 }
5877 
5878 
5879  // Get the
5880  // UPROPVAL
5881  // node
5882  // pointer
5883  // within
5884  // that
5885  // propset.
5886  pUPropVal =
5887  &(pUProp->
5888  pUPropVal
5889  [iUProp]);
5890 
5891 ATLASSERT
5892  (pUPropVal);
5893 
5894 
5895  // Handle
5896  // VT_EMPTY,
5897  // which
5898  // indicates
5899  // to the
5900  // provider
5901  // to
5902  // reset this
5903  // property
5904  // to the
5905  // providers
5906  // default
5907  if (pDBProp->
5908  vValue.
5909  vt ==
5910  VT_EMPTY)
5911 
5912  {
5913 
5914 if
5915  (pUPropInfo->
5916  dwFlags &
5917  DBPROPFLAGS_COLUMNOK)
5918 
5919  {
5920 
5921  // Remove any
5922  // nodes,
5923  // because
5924  // the
5925  // default
5926  // applies to
5927  //
5928  // all
5929  // columns
5930  delete
5931  pUPropVal->
5932  pCColumnIds;
5933 
5934 pUPropVal->
5935  pCColumnIds =
5936  NULL;
5937 }
5938 
5939 
5940  // Should
5941  // clear
5942  // here,
5943  // since
5944  // previous
5945  // values may
5946  // already
5947  // have been
5948  // cached and
5949  // need to be
5950  // replaced.
5951  VariantClear
5952  (&
5953  (pUPropVal->
5954  vValue));
5955 
5956 
5957 pUPropVal->
5958  dwFlags &=
5960 
5961 hr =
5962  GetDefaultValue
5963  (iCurSet,
5964  pDBProp->
5965  dwPropertyID,
5966 
5967 &
5968  (pUPropVal->
5969  dwOption),
5970  &(pUPropVal->
5971  vValue));
5972 
5973 
5974 goto EXIT;
5975 
5976 }
5977 
5978 
5979 
5980  // Column
5981  // Level
5982  if
5983  (pUPropInfo->
5984  dwFlags &
5985  DBPROPFLAGS_COLUMNOK)
5986 
5987  {
5988 
5989  // Check to
5990  // see if it
5991  // applies to
5992  // all
5993  if ((CompareDBIDs (&(pDBProp->colid), &DB_NULLID) == S_OK))
5994  {
5995 
5996  // Remove the
5997  // Columns
5998  // Storage
5999  // object
6000  delete
6001  pUPropVal->
6002  pCColumnIds;
6003 
6004 pUPropVal->
6005  pCColumnIds =
6006  NULL;
6007 
6008 pUPropVal->
6009  dwOption =
6010  pDBProp->
6011  dwOptions;
6012 
6013 if (FAILED
6014  (hr =
6015  VariantCopy
6016  (&
6017  (pUPropVal->
6018  vValue),
6019 
6020 &
6021  (pDBProp->
6022  vValue))))
6023 
6024  goto EXIT;
6025 
6026 pUPropVal->
6027  dwFlags |=
6029 
6030 }
6031 
6032  else // Does
6033  // not
6034  // apply
6035  // to
6036  // all
6037  // columns
6038  {
6039 
6040 if
6041  (pUPropVal->
6042  pCColumnIds
6043  ==
6044  NULL)
6045  ATLTRY
6046  (pUPropVal->
6047  pCColumnIds =
6048  new
6049  CColumnIds)
6050 
6051 if
6052  (pUPropVal->
6053  pCColumnIds)
6054 
6055  {
6056 
6057 if (FAILED
6058  (hr =
6059  (pUPropVal->
6060  pCColumnIds)->
6061  AddColumnId
6062  (pDBProp)))
6063 
6064  goto EXIT;
6065 
6066 pUPropVal->
6067  dwFlags |=
6069 
6070 }
6071 
6072  else
6073 
6074  {
6075 
6076 hr =
6077  E_OUTOFMEMORY;
6078 
6079 goto EXIT;
6080 }
6081 
6082 
6083 }
6084 
6085 }
6086 
6087  else
6088 
6089  {
6090 
6091  // Set for
6092  // non-column
6093  // level
6094  // properties
6095  pUPropVal->
6096  dwOption =
6097  pDBProp->
6098  dwOptions;
6099 
6100  // Our
6101  // provider
6102  // has no
6103  // limit on
6104  // the
6105  // maximum
6106  // number of
6107  // rows
6108  // that can
6109  // have
6110  // pending
6111  // changes,
6112  // therefore
6113  // the value
6114  // of the
6115  // DBPROP_MAXPENDINGROWS
6116  // property
6117  // will
6118  // always be
6119  // zero
6120  // (default),
6121  // regardless
6122  // of what
6123  // the user
6124  // attempts
6125  // to set it
6126  // to.
6127  // In the
6128  // code
6129  // below, we
6130  // modify the
6131  // property
6132  // value only
6133  // if
6134  // this is
6135  // not the
6136  // DBPROP_MAXPENDINGROWS
6137  // property.
6138  if (pDBProp->
6139  dwPropertyID
6140  !=
6141  DBPROP_MAXPENDINGROWS)
6142 
6143  {
6144 
6145 if (FAILED
6146  (hr =
6147  VariantCopy
6148  (&
6149  (pUPropVal->
6150  vValue),
6151 
6152 &
6153  (pDBProp->
6154  vValue))))
6155 
6156  goto EXIT;
6157 
6158 }
6159 
6160 if (FAILED
6161  (hr =
6162  OnPropertyChanged
6163  (iCurSet,
6164  pDBProp)))
6165 
6166  goto EXIT;
6167 
6168 pUPropVal->
6169  dwFlags |=
6171 
6172 }
6173 
6174 
6175 EXIT:
6176 if (hr ==
6177  S_OK)
6178  pDBProp->
6179  dwStatus =
6180  DBPROPSTATUS_OK;
6181 
6182 
6183 return hr;
6184 
6185 }
6186 
6187 
6188 HRESULT SetProperties (const DWORD /* dwStatus
6189  */
6190  ,
6191  const
6192  ULONG
6193  cPropertySets,
6194 
6195 const
6196  DBPROPSET
6197  rgPropertySets
6198  [],
6199  const
6200  ULONG
6201  cSelectProps
6202  =
6203  1,
6204 
6205 const
6206  GUID
6207  *
6208  const
6209  ppGuid
6210  []
6211  =
6212  NULL,
6213  bool
6214  bIsCreating
6215  =
6216  false)
6217 
6218  {
6219 
6220 DWORD dwState
6221  = 0;
6222 
6223 ULONG
6224  ulCurSet,
6225  ulCurProp,
6226  ulProp;
6227 
6228 DBPROP *
6229  rgDBProp;
6230 
6231 UPROPINFO *
6232  pUPropInfo;
6233 
6234 CComVariant
6235  vDefaultValue;
6236 
6237 DWORD
6238  dwOption;
6239 
6240 
6241 CComCritSecLock
6242  <
6243  CComAutoCriticalSection
6244  >
6245  lock
6246  (m_oCriticalSection);
6247 
6248 
6249  // ppGuid
6250  // specifies
6251  // the
6252  // property
6253  // sets that
6254  // the
6255  // consumer
6256  // can set
6257  // based
6258  // on the
6259  // interface
6260  // that
6261  // called
6262  // this
6263  // function.
6264  ATLASSERT
6265  (ppGuid !=
6266  NULL);
6267 
6268 
6269 if ((cPropertySets != 0) && (rgPropertySets == NULL))
6270  return E_INVALIDARG;
6271 
6272  // Process
6273  // property
6274  // sets
6275  for (ULONG
6276  ulSet =
6277  0;
6278  ulSet <
6279  cPropertySets;
6280  ulSet++)
6281 
6282  {
6283 
6284 if ((rgPropertySets[ulSet].cProperties != 0) && (rgPropertySets[ulSet].rgProperties == NULL))
6285  return E_INVALIDARG;
6286 
6287 bool bAvailable = false;
6288 for (ULONG l = 0; l < cSelectProps; l++)
6289  {
6290 
6291 if
6292  (InlineIsEqualGUID
6293  (*ppGuid[l],
6294  rgPropertySets
6295  [ulSet].
6296  guidPropertySet))
6297 
6298  bAvailable
6299  |= true;
6300 }
6301 
6302 
6303  // Make sure
6304  // we support
6305  // the
6306  // property
6307  // set
6308  if
6309  (!bAvailable
6310  ||
6311 
6312  (GetIndexofPropSet
6313  (&
6314  (rgPropertySets
6315  [ulSet].
6316  guidPropertySet),
6317  &ulCurSet)
6318  ==
6319  S_FALSE))
6320  {
6321 
6322  // Not
6323  // supported,
6324  // thus we
6325  // need to
6326  // mark all
6327  // as
6328  // NOT_SUPPORTED
6329  rgDBProp =
6330  rgPropertySets
6331  [ulSet].
6332  rgProperties;
6333 
6334 for (ulProp =
6335  0;
6336  ulProp <
6337  rgPropertySets
6338  [ulSet].
6339  cProperties;
6340  ulProp++)
6341 
6342  {
6343 
6344 dwState |=
6345  SETPROP_ERRORS;
6346 
6347 dwState |=
6348  (rgDBProp
6349  [ulProp].
6350  dwOptions ==
6351  DBPROPOPTIONS_REQUIRED)
6352  ?
6353  SETPROP_WAS_REQUIRED
6354  : 0;
6355 
6356 rgDBProp
6357  [ulProp].
6358  dwStatus =
6359  DBPROPSTATUS_NOTSUPPORTED;
6360 
6362  (rgPropertySets
6363  [ulSet].
6364  guidPropertySet,
6365  dwState);
6366 }
6367 
6368 continue;
6369 }
6370 
6371 
6372  // Handle
6373  // property
6374  // sets
6375  // marked as
6376  // pass
6377  // through
6378  if
6379  (m_pUPropSet
6380  [ulCurSet].
6381  dwFlags &
6382  UPROPSET_PASSTHROUGH)
6383 
6384  {
6385 
6386 HRESULT hr =
6387  SetPassThrough
6388  (&rgPropertySets
6389  [ulSet]);
6390 
6391 if (hr ==
6392  DB_E_ERRORSOCCURRED)
6393 
6394  {
6395 
6396 dwState |=
6397  SETPROP_ERRORS;
6398 
6399 dwState |=
6400  SETPROP_WAS_REQUIRED;
6401 
6402 }
6403 
6404  else
6405  if (hr ==
6406  DB_S_ERRORSOCCURRED)
6407 
6408  {
6409 
6410 dwState |=
6411  SETPROP_ERRORS;
6412 
6413 dwState |=
6414  SETPROP_VALIDPROP;
6415 
6416 }
6417 
6418  else
6419 
6420  {
6421 
6422 ATLASSERT (hr
6423  ==
6424  S_OK);
6425 
6426 dwState |=
6427  SETPROP_VALIDPROP;
6428 
6429 }
6430 
6431 
6432 continue;
6433 }
6434 
6435 
6436  // Handle
6437  // properties
6438  // of a
6439  // supported
6440  // property
6441  // set
6442  rgDBProp =
6443  rgPropertySets
6444  [ulSet].
6445  rgProperties;
6446 
6447 for (ulProp =
6448  0;
6449  ulProp <
6450  rgPropertySets
6451  [ulSet].
6452  cProperties;
6453  ulProp++)
6454 
6455  {
6456 
6457  // Is this a
6458  // supported
6459  // PROPID for
6460  // this
6461  // property
6462  // set
6463  if
6464  (GetIndexofPropIdinPropSet
6465  (ulCurSet,
6466  rgDBProp
6467  [ulProp].
6468  dwPropertyID,
6469 
6470 &ulCurProp)
6471  == S_FALSE)
6472  {
6473 
6474 dwState |=
6475  SETPROP_ERRORS;
6476 
6477 dwState |=
6478  (rgDBProp
6479  [ulProp].
6480  dwOptions ==
6481  DBPROPOPTIONS_REQUIRED)
6482  ?
6483  SETPROP_WAS_REQUIRED
6484  : 0;
6485 
6486 rgDBProp
6487  [ulProp].
6488  dwStatus =
6489  DBPROPSTATUS_NOTSUPPORTED;
6490 
6492  (rgDBProp
6493  [ulProp].
6494  dwPropertyID,
6495  rgDBProp
6496  [ulProp].
6497  dwStatus);
6498 
6499 continue;
6500 }
6501 
6502 
6503  // Set the
6504  // pUPropInfo
6505  // pointer
6506  pUPropInfo =
6507  &(m_pUPropSet
6508  [ulCurSet].
6509  pUPropInfo
6510  [ulCurProp]);
6511 
6512 ATLASSERT
6513  (pUPropInfo);
6514 
6515 
6516  // check
6517  // dwOption
6518  // for a
6519  // valid
6520  // option
6521  if ((rgDBProp
6522  [ulProp].
6523  dwOptions
6524  !=
6525  DBPROPOPTIONS_REQUIRED)
6526  &&
6527 
6528 (rgDBProp
6529  [ulProp].
6530  dwOptions
6531  !=
6532  DBPROPOPTIONS_SETIFCHEAP))
6533 
6534  {
6535 
6536 ATLTRACE
6537  (atlTraceDBProvider,
6538  0,
6539  _T
6540  ("SetProperties dwOptions Invalid: %u\n"),
6541  rgDBProp
6542  [ulProp].
6543  dwOptions);
6544 
6545 dwState |=
6546  SETPROP_ERRORS;
6547 
6548 dwState |=
6549  SETPROP_WAS_REQUIRED;
6550 
6551 rgDBProp
6552  [ulProp].
6553  dwStatus =
6554  DBPROPSTATUS_BADOPTION;
6555 
6557  (rgDBProp
6558  [ulProp].
6559  dwPropertyID,
6560  rgDBProp
6561  [ulProp].
6562  dwStatus);
6563 
6564 continue;
6565 }
6566 
6567 
6568  // Check that
6569  // the
6570  // property
6571  // is
6572  // settable
6573  // We do not
6574  // check
6575  // against
6576  // DBPROPFLAGS_CHANGE
6577  // here
6578  if ((pUPropInfo->dwFlags & DBPROPFLAGS_WRITE) == 0)
6579  {
6580 
6581 rgDBProp
6582  [ulProp].
6583  dwStatus =
6584  DBPROPSTATUS_OK;
6585 
6586 
6587 vDefaultValue.
6588  Clear ();
6589 
6590  // VT_EMPTY
6591  // against a
6592  // read only
6593  // property
6594  // should be
6595  // a no-op
6596  // since
6597  // the
6598  // VT_EMPTY
6599  // means the
6600  // default.
6601  if (V_VT
6602  (&rgDBProp
6603  [ulProp].
6604  vValue)
6605  ==
6606  VT_EMPTY)
6607 
6608  {
6609 
6610 dwState |=
6611  SETPROP_VALIDPROP;
6612 
6613 continue;
6614 }
6615 
6616 
6617 if
6618  (SUCCEEDED
6619  (GetDefaultValue
6620  (ulCurSet,
6621  rgDBProp
6622  [ulProp].
6623  dwPropertyID,
6624 
6625 &dwOption,
6626  &
6627  (vDefaultValue))))
6628 
6629  {
6630 
6631 if (V_VT
6632  (&rgDBProp
6633  [ulProp].
6634  vValue)
6635  ==
6636  V_VT
6637  (&vDefaultValue))
6638 
6639  {
6640 
6641 switch (V_VT
6642  (&vDefaultValue))
6643 
6644  {
6645 
6646 case VT_BOOL:
6647 
6648 if (V_BOOL
6649  (&rgDBProp
6650  [ulProp].
6651  vValue)
6652  ==
6653  V_BOOL
6654  (&vDefaultValue))
6655 
6656  {
6657 
6658 dwState |=
6659  SETPROP_VALIDPROP;
6660 
6661 continue;
6662 }
6663 
6664 break;
6665 case VT_I2:
6666 
6667 if (V_I2
6668  (&rgDBProp
6669  [ulProp].
6670  vValue)
6671  ==
6672  V_I2
6673  (&vDefaultValue))
6674 
6675  {
6676 
6677 dwState |=
6678  SETPROP_VALIDPROP;
6679 
6680 continue;
6681 }
6682 
6683 break;
6684 case VT_I4:
6685 
6686 if (V_I4
6687  (&rgDBProp
6688  [ulProp].
6689  vValue)
6690  ==
6691  V_I4
6692  (&vDefaultValue))
6693 
6694  {
6695 
6696 dwState |=
6697  SETPROP_VALIDPROP;
6698 
6699 continue;
6700 }
6701 
6702 break;
6703 case VT_BSTR:
6704 
6705 if (wcscmp
6706  (V_BSTR
6707  (&rgDBProp
6708  [ulProp].
6709  vValue),
6710  V_BSTR
6711  (&vDefaultValue))
6712  == 0)
6713  {
6714 
6715 dwState |=
6716  SETPROP_VALIDPROP;
6717 
6718 continue;
6719 }
6720 
6721 break;
6722 }
6723 
6724 }
6725 
6726 }
6727 
6728 
6729 dwState |=
6730  SETPROP_ERRORS;
6731 
6732 dwState |=
6733  (rgDBProp
6734  [ulProp].
6735  dwOptions ==
6736  DBPROPOPTIONS_REQUIRED)
6737  ?
6738  SETPROP_WAS_REQUIRED
6739  : 0;
6740 
6741 rgDBProp
6742  [ulProp].
6743  dwStatus =
6744  (rgDBProp
6745  [ulProp].
6746  dwOptions ==
6747  DBPROPOPTIONS_OPTIONAL)
6748  ?
6749  DBPROPSTATUS_NOTSET
6750  :
6751  DBPROPSTATUS_NOTSETTABLE;
6752 
6754  (rgDBProp
6755  [ulProp].
6756  dwPropertyID,
6757  rgDBProp
6758  [ulProp].
6759  dwStatus);
6760 
6761 continue;
6762 }
6763 
6764 
6765  // Check that
6766  // the
6767  // property
6768  // is being
6769  // set with
6770  // the
6771  // correct
6772  // VARTYPE
6773  if ((rgDBProp
6774  [ulProp].
6775  vValue.
6776  vt !=
6777  pUPropInfo->
6778  VarType)
6779  &&
6780 
6781 (rgDBProp
6782  [ulProp].
6783  vValue.
6784  vt !=
6785  VT_EMPTY))
6786 
6787  {
6788 
6789 dwState |=
6790  SETPROP_ERRORS;
6791 
6792 dwState |=
6793  (rgDBProp
6794  [ulProp].
6795  dwOptions ==
6796  DBPROPOPTIONS_REQUIRED)
6797  ?
6798  SETPROP_WAS_REQUIRED
6799  : 0;
6800 
6801 rgDBProp
6802  [ulProp].
6803  dwStatus =
6804  DBPROPSTATUS_BADVALUE;
6805 
6807  (rgDBProp
6808  [ulProp].
6809  dwPropertyID,
6810  rgDBProp
6811  [ulProp].
6812  dwStatus);
6813 
6814 continue;
6815 }
6816 
6817 
6818  // Check that
6819  // the value
6820  // is legal
6821  if ((rgDBProp
6822  [ulProp].
6823  vValue.
6824  vt !=
6825  VT_EMPTY)
6826  &&
6827 
6828 IsValidValue
6829  (ulCurSet,
6830  &
6831  (rgDBProp
6832  [ulProp]))
6833  ==
6834  S_FALSE)
6835  {
6836 
6837 dwState |=
6838  SETPROP_ERRORS;
6839 
6840 dwState |=
6841  (rgDBProp
6842  [ulProp].
6843  dwOptions ==
6844  DBPROPOPTIONS_REQUIRED)
6845  ?
6846  SETPROP_WAS_REQUIRED
6847  : 0;
6848 
6849 rgDBProp
6850  [ulProp].
6851  dwStatus =
6852  DBPROPSTATUS_BADVALUE;
6853 
6855  (rgDBProp
6856  [ulProp].
6857  dwPropertyID,
6858  rgDBProp
6859  [ulProp].
6860  dwStatus);
6861 
6862 continue;
6863 }
6864 
6865 
6866 
6867  // Check for
6868  // a bad
6869  // COLID, we
6870  // only catch
6871  // bad DBIDs
6872  if
6873  (pUPropInfo->
6874  dwFlags &
6875  DBPROPFLAGS_COLUMNOK)
6876 
6877  {
6878 
6879 if
6880  (CDBIDOps::
6881  IsValidDBID
6882  (&
6883  (rgDBProp
6884  [ulProp].
6885  colid)) ==
6886  S_FALSE)
6887  {
6888 
6889 dwState |=
6890  SETPROP_ERRORS;
6891 
6892 dwState |=
6893  (rgDBProp
6894  [ulProp].
6895  dwOptions ==
6896  DBPROPOPTIONS_REQUIRED)
6897  ?
6898  SETPROP_WAS_REQUIRED
6899  : 0;
6900 
6901 rgDBProp
6902  [ulProp].
6903  dwStatus =
6904  DBPROPSTATUS_BADCOLUMN;
6905 
6907  (rgDBProp
6908  [ulProp].
6909  dwPropertyID,
6910  rgDBProp
6911  [ulProp].
6912  dwStatus);
6913 
6914 continue;
6915 }
6916 
6917 dwState |=
6918  SETPROP_COLUMN_LEVEL;
6919 
6920 
6921 }
6922 
6923 
6924 if (SetProperty (ulCurSet, ulCurProp, /* pUPropInfo,
6925  */
6926  &
6927  (rgDBProp
6928  [ulProp]))
6929  ==
6930  S_OK)
6931  {
6932 
6933 dwState |=
6934  SETPROP_VALIDPROP;
6935 
6936 }
6937 
6938  else
6939 
6940  {
6941 
6942 dwState |=
6943  SETPROP_ERRORS;
6944 
6945 dwState |=
6946  (rgDBProp
6947  [ulProp].
6948  dwOptions ==
6949  DBPROPOPTIONS_REQUIRED)
6950  ?
6951  SETPROP_WAS_REQUIRED
6952  : 0;
6953 }
6954 
6956  (rgDBProp
6957  [ulProp].
6958  dwPropertyID,
6959  rgDBProp
6960  [ulProp].
6961  dwStatus);
6962 }
6963 
6964 }
6965 
6966 
6967 vDefaultValue.
6968  Clear ();
6969 
6970  // At least
6971  // one propid
6972  // was marked
6973  // as not
6974  // S_OK
6975  if (dwState &
6976  SETPROP_ERRORS)
6977 
6978  {
6979 
6980 if
6981  (!bIsCreating)
6982 
6983  {
6984 
6985 return
6986  (dwState &
6987  SETPROP_VALIDPROP)
6988  ?
6989  DB_S_ERRORSOCCURRED
6990  :
6991  DB_E_ERRORSOCCURRED;
6992 
6993 }
6994 
6995  else
6996 
6997  {
6998 
6999 return
7000  (dwState &
7001  SETPROP_WAS_REQUIRED)
7002  ?
7003  DB_E_ERRORSOCCURRED
7004  :
7005  DB_S_ERRORSOCCURRED;
7006 
7007 }
7008 
7009 }
7010 
7011 
7012 return S_OK;
7013 }
7014 
7015 
7017  HRESULT
7018  CopyUPropVal
7019  (ULONG
7020  iPropSet,
7021  UPROPVAL *
7022  rgUPropVal)
7023  {
7024 
7025 HRESULT hr =
7026  S_OK;
7027 
7028 UPROP *
7029  pUProp;
7030 
7031 UPROPVAL *
7032  pUPropVal;
7033 
7034 DBPROP
7035  dbProp;
7036 
7037 
7038 ATLASSERT
7039  (rgUPropVal);
7040 
7041 ATLASSERT
7042  (iPropSet <
7043  m_cUPropSet);
7044 
7045 
7046 VariantInit
7047  (&dbProp.
7048  vValue);
7049 
7050 
7051 pUProp =
7052  &(m_pUProp
7053  [iPropSet]);
7054 
7055 for (ULONG ul
7056  = 0;
7057  ul <
7058  pUProp->
7059  cPropIds;
7060  ul++)
7061  {
7062 
7063 pUPropVal =
7064  &(pUProp->
7065  pUPropVal
7066  [ul]);
7067 
7068  // Transfer
7069  // dwOptions
7070  rgUPropVal
7071  [ul].
7072  dwOption =
7073  pUPropVal->
7074  dwOption;
7075 
7076  // Transfer
7077  // Flags
7078  rgUPropVal
7079  [ul].dwFlags =
7080  pUPropVal->
7081  dwFlags;
7082 
7083  // Transfer
7084  // Column
7085  // Properties
7086  if
7087  (pUPropVal->
7088  pCColumnIds)
7089 
7090  {
7091 
7092 ATLTRY
7093  (rgUPropVal
7094  [ul].
7095  pCColumnIds =
7096  new
7097  CColumnIds)
7098  if (rgUPropVal
7099  [ul].
7100  pCColumnIds)
7101 
7102  {
7103 
7104 CColumnIds *
7105  pColIds =
7106  pUPropVal->
7107  pCColumnIds;
7108 
7109 for (size_t i
7110  = 0;
7111  i <
7112  pColIds->
7113  GetCount
7114  ();
7115  i++)
7116  {
7117 
7118 hr =
7119  (pUPropVal->
7120  pCColumnIds)->
7121  GetValue (i,
7122  &
7123  (dbProp.
7124  dwOptions),
7125  &
7126  (dbProp.
7127  colid),
7128  &
7129  (dbProp.
7130  vValue));
7131 
7132 if (FAILED
7133  (hr))
7134  goto EXIT;
7135 
7136 if (FAILED
7137  (hr =
7138  (rgUPropVal
7139  [ul].
7140  pCColumnIds)->
7141  AddColumnId
7142  (&dbProp)))
7143 
7144  goto EXIT;
7145 
7146 }
7147 
7148 }
7149 
7150  else
7151 
7152  {
7153 
7154 hr =
7155  E_OUTOFMEMORY;
7156 
7157 goto EXIT;
7158 }
7159 
7160 }
7161 
7162  else
7163 
7164  {
7165 
7166 rgUPropVal
7167  [ul].
7168  pCColumnIds =
7169  NULL;
7170 }
7171 
7172 
7173  // Transfer
7174  // value
7175  VariantInit (&
7176  (rgUPropVal
7177  [ul].
7178  vValue));
7179 
7180 if (FAILED
7181  (hr =
7182  VariantCopy
7183  (&
7184  (rgUPropVal
7185  [ul].
7186  vValue),
7187 
7188 &
7189  (pUPropVal->
7190  vValue))))
7191 
7192  goto EXIT;
7193 
7194 }
7195 
7196 
7197 EXIT:
7198 VariantClear
7199  (&
7200  (dbProp.
7201  vValue));
7202 
7203 return hr;
7204 }
7205 
7206 void
7207  ClearPropertyInError
7208  ()
7209  {
7210 
7211 ATLASSERT
7212  (m_rgdwPropsInError);
7213 
7214 memset
7215  (m_rgdwPropsInError,
7216  0,
7217  m_cUPropSet *
7218  m_cElemPerSupported
7219  *
7220  sizeof
7221  (DWORD));
7222 }
7223 
7224 
7225 void
7226  CopyUPropSetsSupported
7227  (DWORD *
7228  rgdwSupported)
7229 
7230  {
7231 
7232 memcpy
7233  (rgdwSupported,
7234  m_rgdwSupported,
7235  m_cUPropSet *
7236  m_cElemPerSupported
7237  *
7238  sizeof
7239  (DWORD));
7240 }
7241 
7242 
7243 virtual
7244  HRESULT
7245  InitUPropSetsSupported
7246  () = 0;
7247 
7248 
7249 virtual
7250  HRESULT
7251  GetIndexofPropSet
7252  (const GUID *
7253  pPropSet,
7254  ULONG *
7255  pulCurSet) =
7256  0;
7257 
7258 
7259 ULONG
7260  GetCountofWritablePropsInPropSet
7261  (ULONG
7262  iPropSet)
7263  {
7264 
7265 ULONG
7266  cWritable = 0;
7267 
7268 UPROPINFO *
7269  pUPropInfo;
7270 
7271 
7272 ATLASSERT
7273  (m_pUPropSet);
7274 
7275 ATLASSERT
7276  (iPropSet <
7277  m_cUPropSet);
7278 
7279 
7280 pUPropInfo =
7281  m_pUPropSet
7282  [iPropSet].
7283  pUPropInfo;
7284 
7285 
7286 for (ULONG
7287  ul = 0;
7288  ul <
7289  m_pUPropSet
7290  [iPropSet].
7291  cUPropInfo;
7292  ul++)
7293  {
7294 
7295 if
7296  (pUPropInfo
7297  [ul].
7298  dwFlags &
7299  (DBPROPFLAGS_WRITE
7300  |
7302 
7303  cWritable++;
7304 
7305 }
7306 
7307 
7308 return
7309  cWritable;
7310 }
7311 
7312 
7313 void
7314  CopyUPropInfo
7315  (ULONG
7316  iPropSet,
7317  UPROPINFO **
7318  rgpUPropInfo)
7319 
7320  {
7321 
7322 ATLASSERT
7323  (rgpUPropInfo);
7324 
7325 ATLASSERT
7326  (iPropSet <
7327  m_cUPropSet);
7328 
7329 memcpy
7330  (rgpUPropInfo,
7331  m_pUProp
7332  [iPropSet].
7333  rgpUPropInfo,
7334  m_pUProp
7335  [iPropSet].
7336  cPropIds *
7337  sizeof
7338  (UPROPINFO
7339  *));
7340 }
7341 
7342 
7343 virtual
7344  HRESULT
7345  GetDefaultValue
7346  (ULONG
7347  iPropSet,
7348  DBPROPID
7349  dwPropId,
7350  DWORD *
7351  pdwOption,
7352  VARIANT *
7353  pVar) = 0;
7354 
7355 
7356 typedef
7357  UPROPSET *
7358  (*PGetPropSet)
7359  (ULONG *
7360  pNumPropSets,
7361  ULONG *
7362  pcElemPerSupported,
7363  UPROPSET *
7364  pSet,
7365  GUID *
7366  pguidSet);
7367 
7368 
7369 HRESULT
7370  InternalInitUPropSetsSupported
7371  (PGetPropSet
7372  pfnGetSet)
7373  {
7374 
7375 ULONG
7376  cPropSet =
7377  0,
7378  cElemsPerSupported
7379  = 0;
7380 
7381 int cSets =
7382  (int)
7383  (DWORD_PTR)
7384  (*pfnGetSet)
7385  (NULL,
7386  &cElemsPerSupported,
7387  NULL,
7388  (GUID *) &
7389  GUID_NULL);
7390 
7391 UPROPSET *
7392  pPropSet =
7393  (UPROPSET *)
7394  CoTaskMemAlloc
7395  (sizeof
7396  (UPROPSET) *
7397  cSets);
7398 
7399 if (pPropSet
7400  ==
7401  NULL)
7402  return
7403  E_OUTOFMEMORY;
7404 
7405 pPropSet =
7406  (*pfnGetSet)
7407  (&cPropSet,
7408  &cElemsPerSupported,
7409  pPropSet,
7410  (GUID *) &
7411  GUID_NULL);
7412 
7413 memset
7414  (m_rgdwSupported,
7415  0xFFFF,
7416  cPropSet *
7417  cElemsPerSupported
7418  *
7419  sizeof
7420  (DWORD));
7421 
7422 CoTaskMemFree
7423  (pPropSet);
7424 
7425 return S_OK;
7426 
7427 }
7428 
7429 
7430 HRESULT
7431  InternalGetDefaultValue
7432  (PGetPropSet
7433  pfnGetSet,
7434  ULONG
7435  iPropSet,
7436  DBPROPID
7437  dwPropId,
7438  DWORD *
7439  pdwOption,
7440  VARIANT *
7441  pVar)
7442  {
7443 
7444 if (pdwOption
7445  == NULL
7446  || pVar
7447  ==
7448  NULL)
7449  return
7450  E_INVALIDARG;
7451 
7452 
7453 ULONG
7454  cUPropSet =
7455  0,
7456  cElemPerSupported
7457  = 0;
7458 
7459 
7460 int cSets =
7461  (int)
7462  (DWORD_PTR)
7463  (*pfnGetSet)
7464  (NULL,
7465  &cElemPerSupported,
7466  NULL,
7467  (GUID *) &
7468  GUID_NULL);
7469 
7470 UPROPSET *
7471  pPropSet =
7472  (UPROPSET *)
7473  CoTaskMemAlloc
7474  (sizeof
7475  (UPROPSET) *
7476  cSets);
7477 
7478 if (pPropSet
7479  ==
7480  NULL)
7481  return
7482  E_OUTOFMEMORY;
7483 
7484 pPropSet =
7485  (*pfnGetSet)
7486  (&cUPropSet,
7487  &cElemPerSupported,
7488  pPropSet,
7489  (GUID *) &
7490  GUID_NULL);
7491 
7492 
7493 ATLASSERT
7494  (iPropSet <
7495  cUPropSet);
7496 
7497 for (ULONG
7498  iProp =
7499  0;
7500  iProp <
7501  pPropSet
7502  [iPropSet].
7503  cUPropInfo;
7504  iProp++)
7505 
7506  {
7507 
7508 UPROPINFO &
7509  rInfo =
7510  pPropSet
7511  [iPropSet].
7512  pUPropInfo
7513  [iProp];
7514 
7515 if (rInfo.
7516  dwPropId
7517  ==
7518  dwPropId)
7519 
7520  {
7521 
7522 HRESULT hr =
7523  S_OK;
7524 
7525 pVar->vt =
7526  rInfo.VarType;
7527 
7528 *pdwOption =
7529  rInfo.
7530  dwOption;
7531 
7532 switch
7533  (rInfo.
7534  VarType)
7535  {
7536 
7537 case VT_BSTR:
7538 
7539 pVar->bstrVal = SysAllocString (rInfo.szVal);
7540 if (pVar->bstrVal == NULL && rInfo.szVal != NULL)
7541  hr = E_OUTOFMEMORY;
7542 break;
7543 default:
7544 
7545 pVar->lVal =
7546  (DWORD) rInfo.
7547  dwVal;
7548 break;
7549 
7550 }
7551 
7552 CoTaskMemFree
7553  (pPropSet);
7554 
7555 return hr;
7556 }
7557 
7558 }
7559 
7560 CoTaskMemFree
7561  (pPropSet);
7562 
7563 return
7564  E_FAIL;
7565 }
7566 
7567 
7568 HRESULT
7569  InternalFInit
7570  (PGetPropSet
7571  pfnGetSet,
7573  * pCopyMe =
7574  NULL)
7575  {
7576 
7577 HRESULT hr;
7578 
7579 ULONG
7580  ulPropId;
7581 
7582 ULONG
7583  cPropIds;
7584 
7585 ULONG
7586  iPropSet;
7587 
7588 ULONG
7589  iNewDex;
7590 
7591 UPROPINFO *
7592  pUPropInfo;
7593 
7594  // If a
7595  // pointer is
7596  // passed in,
7597  // we should
7598  // copy that
7599  // property
7600  // object
7601  if (pCopyMe)
7602  {
7603 
7604  // Establish
7605  // some base
7606  // values
7607  m_cUPropSet =
7608  pCopyMe->
7609  m_cUPropSet;
7610 
7611 CoTaskMemFree
7612  (m_pUPropSet);
7613 
7614 m_pUPropSet =
7615  (UPROPSET *)
7616  CoTaskMemAlloc
7617  (sizeof
7618  (UPROPSET) *
7619  m_cUPropSet);
7620 
7621 if
7622  (m_pUPropSet
7623  ==
7624  NULL)
7625  return
7626  E_OUTOFMEMORY;
7627 
7628 memcpy
7629  (m_pUPropSet,
7630  pCopyMe->
7631  m_pUPropSet,
7632  sizeof
7633  (UPROPSET) *
7634  m_cUPropSet);
7635 
7636 m_cElemPerSupported
7637  =
7638  pCopyMe->
7639  m_cElemPerSupported;
7640 
7641 ATLASSERT ((m_cUPropSet != 0) && (m_cElemPerSupported != 0));
7642  // Retrieve
7643  // Supported
7644  // Bitmask
7645  ATLTRY
7646  (m_rgdwSupported.
7647  Allocate
7648  (m_cUPropSet
7649  *
7650  m_cElemPerSupported));
7651 
7652 ATLTRY
7653  (m_rgdwPropsInError.
7654  Allocate
7655  (m_cUPropSet
7656  *
7657  m_cElemPerSupported));
7658 
7659 if
7660  (m_rgdwSupported
7661  == NULL
7662  ||
7663  m_rgdwPropsInError
7664  == NULL)
7665  {
7666 
7667 m_rgdwSupported.
7668  Free ();
7669 
7670 m_rgdwPropsInError.
7671  Free ();
7672 
7673 return
7674  E_OUTOFMEMORY;
7675 
7676 }
7677 
7678 ClearPropertyInError
7679  ();
7680 
7681 pCopyMe->
7682  CopyUPropSetsSupported
7683  (m_rgdwSupported);
7684 
7685 
7686 }
7687 
7688  else
7689 
7690  {
7691 
7692 int cSets =
7693  (int)
7694  (DWORD_PTR)
7695  (*pfnGetSet)
7696  (NULL,
7697  &m_cElemPerSupported,
7698  NULL,
7699  (GUID *) &
7700  GUID_NULL);
7701 
7702 UPROPSET *
7703  pSet =
7704  (UPROPSET *)
7705  CoTaskMemAlloc
7706  (sizeof
7707  (UPROPSET) *
7708  cSets);
7709 
7710 if (pSet ==
7711  NULL)
7712  return
7713  E_OUTOFMEMORY;
7714 
7715 pSet =
7716  (*pfnGetSet)
7717  (&m_cUPropSet,
7718  &m_cElemPerSupported,
7719  pSet,
7720  (GUID *) &
7721  GUID_NULL);
7722 
7723 CoTaskMemFree
7724  (m_pUPropSet);
7725 
7726 m_pUPropSet =
7727  pSet;
7728 
7729 ATLASSERT ((m_cUPropSet != 0) && (m_cElemPerSupported != 0));
7730 if (!m_cUPropSet || !m_cElemPerSupported)
7731  return E_FAIL;
7732 
7733 ATLTRY (m_rgdwSupported.Allocate (m_cUPropSet * m_cElemPerSupported));
7734 ATLTRY (m_rgdwPropsInError.Allocate (m_cUPropSet * m_cElemPerSupported));
7735 if (m_rgdwSupported == NULL || m_rgdwPropsInError == NULL)
7736  {
7737 
7738 m_rgdwSupported.
7739  Free ();
7740 
7741 m_rgdwPropsInError.
7742  Free ();
7743 
7744 return
7745  E_OUTOFMEMORY;
7746 
7747 }
7748 
7749  else
7750 
7751 ClearPropertyInError
7752  ();
7753 
7754 
7755 if (FAILED
7756  (hr =
7757  InitUPropSetsSupported
7758  ()))
7759  {
7760 
7761 m_rgdwSupported.
7762  Free ();
7763 
7764 return hr;
7765 }
7766 
7767 }
7768 
7769 
7770  // Allocate
7771  // UPROPS
7772  // structures
7773  // for the
7774  // count of
7775  // Property
7776  // sets
7777  ATLTRY
7778  (m_pUProp.
7779  Allocate
7780  (m_cUPropSet));
7781 
7782 if (m_pUProp)
7783 
7784  {
7785 
7786 memset
7787  (m_pUProp, 0,
7788  m_cUPropSet *
7789  sizeof
7790  (UPROP));
7791 }
7792 
7793  else
7794 
7795  {
7796 
7797 m_cUPropSet =
7798  0;
7799 
7800 return
7801  E_OUTOFMEMORY;
7802 
7803 }
7804 
7805 
7806  // With in
7807  // the UPROPS
7808  // Structure
7809  // allocate
7810  // and
7811  // intialize
7812  // the
7813  // Property
7814  // IDs that
7815  // belong to
7816  // this
7817  // property
7818  // set.
7819  for (iPropSet
7820  = 0;
7821  iPropSet
7822  <
7823  m_cUPropSet;
7824  iPropSet++)
7825 
7826  {
7827 
7828 cPropIds =
7829  GetCountofWritablePropsInPropSet
7830  (iPropSet);
7831 
7832 
7833 if (cPropIds
7834  > 0)
7835  {
7836 
7837 CAutoVectorPtr
7838  <
7839  UPROPINFO *
7840  >rgpUPropInfo;
7841 
7842 CAutoVectorPtr
7843  < UPROPVAL >
7844  rgUPropVal;
7845 
7846 
7847 rgpUPropInfo.
7848  Allocate
7849  (cPropIds);
7850 
7851 rgUPropVal.
7852  Allocate
7853  (cPropIds);
7854 
7855 if ((rgpUPropInfo == NULL) || (rgUPropVal == NULL))
7856  {
7857 
7858 return
7859  E_OUTOFMEMORY;
7860 
7861 }
7862 
7863 if (pCopyMe)
7864 
7865  {
7866 
7867 pCopyMe->
7868  CopyUPropInfo
7869  (iPropSet,
7870  rgpUPropInfo);
7871 
7872 if (FAILED
7873  (hr =
7874  pCopyMe->
7875  CopyUPropVal
7876  (iPropSet,
7877  rgUPropVal)))
7878 
7879  return hr;
7880 
7881 }
7882 
7883  else
7884 
7885  {
7886 
7887  // Clear
7888  // Pointer
7889  // Array
7890  memset
7891  (rgpUPropInfo,
7892  0,
7893  cPropIds *
7894  sizeof
7895  (UPROPINFO
7896  *));
7897 
7898  // Set
7899  // Pointer to
7900  // correct
7901  // property
7902  // ids with a
7903  // property
7904  // set
7905  pUPropInfo =
7906  m_pUPropSet
7907  [iPropSet].
7908  pUPropInfo;
7909 
7910  // Set up the
7911  // writable
7912  // property
7913  // buffers
7914  iNewDex = 0;
7915 
7916 for (ulPropId
7917  = 0;
7918  ulPropId
7919  <
7920  m_pUPropSet
7921  [iPropSet].
7922  cUPropInfo;
7923  ulPropId++)
7924 
7925  {
7926 
7927 if
7928  (pUPropInfo
7929  [ulPropId].
7930  dwFlags &
7931  (DBPROPFLAGS_WRITE
7932  |
7934 
7935  {
7936 
7937  // Following
7938  // ATLASSERT
7939  // indicates
7940  // that the
7941  // are more
7942  // writable
7943  // properties
7944  // then space
7945  // allocated
7946  ATLASSERT
7947  (iNewDex <
7948  cPropIds);
7949 
7950 
7951 rgpUPropInfo
7952  [iNewDex] =
7953  &(pUPropInfo
7954  [ulPropId]);
7955 
7956 rgUPropVal
7957  [iNewDex].
7958  dwOption =
7959  DBPROPOPTIONS_SETIFCHEAP;
7960 
7961 rgUPropVal
7962  [iNewDex].
7963  pCColumnIds =
7964  NULL;
7965 
7966 rgUPropVal
7967  [iNewDex].
7968  dwFlags = 0;
7969 
7970 VariantInit
7971  (&
7972  (rgUPropVal
7973  [iNewDex].
7974  vValue));
7975 
7976 GetDefaultValue
7977  (iPropSet,
7978  pUPropInfo
7979  [ulPropId].
7980  dwPropId,
7981 
7982 &(rgUPropVal
7983  [iNewDex].
7984  dwOption),
7985  &(rgUPropVal
7986  [iNewDex].
7987  vValue));
7988 
7989 iNewDex++;
7990 }
7991 
7992 }
7993 
7994 
7995 ATLASSERT
7996  (cPropIds ==
7997  iNewDex);
7998 }
7999 
8000 
8001 
8002 m_pUProp
8003  [iPropSet].
8004  rgpUPropInfo =
8005  rgpUPropInfo.
8006  Detach ();
8007 
8008 m_pUProp
8009  [iPropSet].
8010  pUPropVal =
8011  rgUPropVal.
8012  Detach ();
8013 
8014 m_pUProp
8015  [iPropSet].
8016  cPropIds =
8017  cPropIds;
8018 }
8019 
8020 }
8021 
8022 
8023  // Finally
8024  // determine
8025  // if there
8026  // are any
8027  // hidden
8028  // property
8029  // sets..
8030  // Those
8031  // that do
8032  // not show
8033  // up in
8034  // GetPropertyInfo
8035  // and should
8036  // not be
8037  // returns on
8038  //
8039  // a 0, NULL
8040  // call to
8041  // GetProperties
8042  for (iPropSet
8043  = 0;
8044  iPropSet
8045  <
8046  m_cUPropSet;
8047  iPropSet++)
8048 
8049  {
8050 
8051 if
8052  (m_pUPropSet
8053  [iPropSet].
8054  dwFlags &
8055  UPROPSET_HIDDEN)
8056 
8057  m_cUPropSetHidden++;
8058 
8059 }
8060 
8061 
8062 return S_OK;
8063 }
8064 
8065  // Check the
8066  // arguments
8067  // for Set
8068  // Properties
8069  static HRESULT
8070  SetPropertiesArgChk
8071  (const ULONG
8072  cPropertySets,
8073  const
8074  DBPROPSET
8075  rgPropertySets
8076  [])
8077  {
8078 
8079 if
8080  (cPropertySets
8081  > 0
8082  &&
8083  !rgPropertySets)
8084 
8085  return
8086  E_INVALIDARG;
8087 
8088 
8089  // New
8090  // argument
8091  // check for
8092  // > 1
8093  // cPropertyIDs
8094  // and NULL
8095  // pointer
8096  // for
8097  // array of
8098  // property
8099  // ids.
8100  for (ULONG ul
8101  = 0;
8102  ul <
8103  cPropertySets;
8104  ul++)
8105  {
8106 
8107 if
8108  (rgPropertySets
8109  [ul].
8110  cProperties
8111  &&
8112  !
8113  (rgPropertySets
8114  [ul].
8115  rgProperties))
8116 
8117  return
8118  E_INVALIDARG;
8119 
8120 }
8121 
8122 
8123 return S_OK;
8124 }
8125 
8126 HRESULT
8127  GetProperties
8128  (const ULONG
8129  cPropertySets,
8130  const
8131  DBPROPIDSET
8132  rgPropertySets
8133  [],
8134 
8135 ULONG *
8136  pcProperties,
8137  DBPROPSET **
8138  prgProperties,
8139 
8140 const ULONG
8141  cSelectProps
8142  =
8143  1,
8144  const GUID *
8145  const
8146  ppGuid[] =
8147  NULL)
8148  {
8149 
8150 UPROPVAL *
8151  pUPropVal;
8152 
8153 ULONG
8154  ulCurProp;
8155 
8156 ULONG
8157  cTmpPropertySets
8158  =
8159  cPropertySets;
8160 
8161 HRESULT hr =
8162  S_OK;
8163 
8164 ULONG ulSet =
8165  0;
8166 
8167 ULONG ulNext
8168  = 0;
8169 
8170 ULONG cSets =
8171  0;
8172 
8173 ULONG cProps
8174  = 0;
8175 
8176 ULONG ulProp
8177  = 0;
8178 
8179 DWORD
8180  dwStatus = 0;
8181 
8182 DBPROP *
8183  pProp = NULL;
8184 
8185 DBPROP *
8186  pCurProp =
8187  NULL;
8188 
8189 DBPROPSET *
8190  pPropSet =
8191  NULL;
8192 
8193 UPROPINFO *
8194  pUPropInfo =
8195  NULL;
8196 // ULONG* piSetIndex = NULL;
8197 // ULONG* piIndex = NULL;
8198  ULONG ulCurSet
8199  = 0;
8200 
8201 ULONG
8202  iPropSet;
8203 
8204 CAutoVectorPtr
8205  < ULONG >
8206  piIndex;
8207 
8208 
8209 CComCritSecLock
8210  <
8211  CComAutoCriticalSection
8212  >
8213  lock
8214  (m_oCriticalSection);
8215 
8216 
8217  // ppGuid
8218  // contains
8219  // an array
8220  // of GUIDs
8221  // that the
8222  // consumer
8223  // can
8224  // retrieve.
8225  // This is
8226  // based upon
8227  // the
8228  // interface
8229  // calling
8230  // this
8231  // function
8232  ATLASSERT
8233  (ppGuid !=
8234  NULL);
8235 
8236  // We need to
8237  // have
8238  // special
8239  // handling
8240  // for
8241  // DBPROPSET_PROPERTIESINERROR..
8242  // Turn on a
8243  // flags to
8244  // indicate
8245  // this mode
8246  // and make
8247  // cTmpPropertySets
8248  // appear to
8249  // be 0
8250  if ((m_dwFlags
8251  &
8253  &&
8254 
8255 rgPropertySets
8256  &&
8257 
8258  (rgPropertySets
8259  [0].
8260  guidPropertySet
8261  ==
8262  DBPROPSET_PROPERTIESINERROR))
8263 
8264  {
8265 
8266 cTmpPropertySets
8267  = 0;
8268 
8269 dwStatus |=
8270  GETPROP_PROPSINERROR;
8271 
8272 }
8273 
8274 
8275  // If the
8276  // consumer
8277  // does not
8278  // restrict
8279  // the
8280  // property
8281  // sets
8282  // by specify
8283  // an array
8284  // of
8285  // property
8286  // sets and a
8287  // cTmpPropertySets
8288  // greater
8289  // than 0,
8290  // then we
8291  // need to
8292  // make sure
8293  // we
8294  // have some
8295  // to return
8296  if
8297  (cTmpPropertySets
8298  == 0)
8299  {
8300 
8301  // There are
8302  // times when
8303  // we are
8304  // called
8305  // from
8306  // IRowsetInfo,
8307  // ISessionProperties,
8308  // etc.
8309  // where we
8310  // should
8311  // return
8312  // only the
8313  // appropriate
8314  // rowset
8315  // when
8316  // cTmpPropertySets
8317  // is
8318  // zero.
8319  // This
8320  // solves the
8321  // problem if
8322  // the user
8323  // has more
8324  // than one
8325  // set
8326  // specified
8327  // in
8328  // their
8329  // PROPSET_MAP.
8330 
8331  // Determine
8332  // the number
8333  // of
8334  // property
8335  // sets
8336  // supported
8337  if (ppGuid ==
8338  NULL)
8339  {
8340 
8341 cSets =
8342  m_cUPropSet;
8343 
8344 }
8345 
8346  else
8347 
8348  {
8349 
8350 ULONG
8351  ulActualProps
8352  = 0;
8353 
8354 CAutoVectorPtr
8355  < ULONG >
8356  piSetIndex;
8357 
8358 
8359 piSetIndex.
8360  Allocate
8361  (cSelectProps);
8362 
8363 if
8364  (piSetIndex ==
8365  NULL)
8366  return
8367  E_OUTOFMEMORY;
8368 
8369 
8370  // Also, find
8371  // the index
8372  // for the
8373  // set we are
8374  // looking
8375  // for
8376  ULONG l;
8377 
8378 for (l = 0;
8379  l <
8380  cSelectProps;
8381  l++)
8382  {
8383 
8384 for
8385  (piSetIndex[l]
8386  = 0;
8387  piSetIndex[l]
8388  <
8389  m_cUPropSet;
8390  piSetIndex
8391  [l]++)
8392  {
8393 
8394 if
8395  (InlineIsEqualGUID
8396  (*m_pUPropSet
8397  [piSetIndex
8398  [l]].
8399  pPropSet,
8400  *ppGuid[l]))
8401 
8402  {
8403 
8404 ulActualProps++;
8405 
8406 break;
8407 }
8408 
8409 }
8410 
8411 }
8412 
8413 
8414 cSets =
8415  ulActualProps;
8416 
8417 ulActualProps
8418  = 0;
8419 
8420 piIndex.
8421  Allocate
8422  (cSets);
8423 
8424 if (piIndex
8425  ==
8426  NULL)
8427  return
8428  E_OUTOFMEMORY;
8429 
8430 for (l = 0;
8431  l <
8432  cSelectProps;
8433  l++)
8434  {
8435 
8436 if (piSetIndex[l] != m_cUPropSet) // this
8437  // is
8438  // an
8439  // invalid
8440  // index
8441  piIndex
8442  [ulActualProps++]
8443  =
8444  piSetIndex[l];
8445 
8446 }
8447 
8448 
8449 }
8450 
8451 }
8452 
8453  else
8454 
8455  {
8456 
8457  // Since
8458  // special
8459  // property
8460  // set guids
8461  // are not
8462  // supported
8463  // by
8464  // GetProperties,
8465  // we can
8466  // just use
8467  // the count
8468  // of
8469  // property
8470  // sets given
8471  // to us.
8472  cSets =
8473  cTmpPropertySets;
8474 
8475 }
8476 
8477 
8478  // If no
8479  // properties
8480  // set, then
8481  // return
8482  if (cSets ==
8483  0)
8484  return S_OK;
8485 
8486 
8487  // Allocate
8488  // the
8489  // DBPROPSET
8490  // structures
8491  pPropSet =
8492  (DBPROPSET *)
8493  CoTaskMemAlloc
8494  (cSets *
8495  sizeof
8496  (DBPROPSET));
8497 
8498 if (pPropSet)
8499 
8500  {
8501 
8502 memset
8503  (pPropSet, 0,
8504  cSets *
8505  sizeof
8506  (DBPROPSET));
8507 
8508 
8509  // Fill in
8510  // the output
8511  // array
8512  iPropSet = 0;
8513 
8514 for (ulSet =
8515  0;
8516  ulSet <
8517  cSets;
8518  ulSet++)
8519 
8520  {
8521 
8522  // Depending
8523  // of if
8524  // Property
8525  // sets are
8526  // specified
8527  // store the
8528  // return
8529  // property
8530  // set.
8531  if
8532  (cTmpPropertySets
8533  == 0)
8534  {
8535 
8536 ULONG lSet;
8537 
8538 
8539 if (ppGuid
8540  [ulSet]
8541  ==
8542  NULL)
8543  lSet = ulSet;
8544 
8545  else
8546 
8547 lSet =
8548  piIndex
8549  [ulSet];
8550 
8551 if
8552  (m_pUPropSet
8553  [lSet].
8554  dwFlags &
8555  UPROPSET_HIDDEN)
8556 
8557  continue;
8558 
8559 
8560 pPropSet
8561  [iPropSet].
8562  guidPropertySet
8563  =
8564  *(m_pUPropSet
8565  [lSet].
8566  pPropSet);
8567 
8568 
8569 }
8570 
8571  else
8572 
8573  {
8574 
8575 pPropSet
8576  [iPropSet].
8577  guidPropertySet
8578  =
8579  rgPropertySets
8580  [ulSet].
8581  guidPropertySet;
8582 
8583 }
8584 
8585 iPropSet++;
8586 }
8587 
8588 }
8589 
8590  else
8591 
8592  {
8593 
8594 ATLTRACE
8595  (atlTraceDBProvider,
8596  0,
8597 
8598 "Could not allocate DBPROPSET array for GetProperties\n");
8599 
8600 return
8601  E_OUTOFMEMORY;
8602 
8603 }
8604 
8605 
8606  // Process
8607  // requested
8608  // or derived
8609  // Property
8610  // sets
8611  iPropSet = 0;
8612 
8613 for (ulSet =
8614  0;
8615  ulSet <
8616  cSets;
8617  ulSet++)
8618 
8619  {
8620 
8621 cProps = 0;
8622 
8623 pProp = NULL;
8624 
8625 ulNext = 0;
8626 
8627 dwStatus &=
8628  (GETPROP_ERRORSOCCURRED
8629  |
8630  GETPROP_VALIDPROP
8631  |
8632  GETPROP_PROPSINERROR);
8633 
8634 
8635  // Calculate
8636  // the number
8637  // of
8638  // property
8639  // nodes
8640  // needed for
8641  // this
8642  // property
8643  // set.
8644  if
8645  (cTmpPropertySets
8646  == 0)
8647  {
8648 
8649 ULONG lSet;
8650 
8651 
8652 if (ppGuid
8653  [ulSet]
8654  ==
8655  NULL)
8656  lSet = ulSet;
8657 
8658  else
8659 
8660 lSet =
8661  piIndex
8662  [ulSet];
8663 
8664  // If
8665  // processing
8666  // requesting
8667  // all
8668  // property
8669  // sets, do
8670  // not
8671  // return the
8672  // hidden
8673  // sets.
8674  if
8675  (m_pUPropSet
8676  [lSet].
8677  dwFlags &
8678  UPROPSET_HIDDEN)
8679 
8680  continue;
8681 
8682 
8683 cProps =
8684  m_pUPropSet
8685  [lSet].
8686  cUPropInfo;
8687 
8688  // Add Enough
8689  // space for
8690  // node that
8691  // are colid
8692  // specific
8693  cProps +=
8694  GetCountofColids
8695  (&
8696  (m_pUProp
8697  [lSet]));
8698 
8699 dwStatus |=
8700  GETPROP_ALLPROPIDS;
8701 
8702 ulCurSet =
8703  lSet;
8704 }
8705 
8706  else
8707 
8708  {
8709 
8710 ATLASSERT
8711  (ulSet ==
8712  iPropSet);
8713 
8714  // If the
8715  // count of
8716  // PROPIDs is
8717  // 0 or It is
8718  // a special
8719  // property
8720  // set, then
8721  //
8722  // the
8723  // consumer
8724  // is
8725  // requesting
8726  // all
8727  // propids
8728  // for this
8729  // property
8730  // set.
8731  if
8732  (rgPropertySets
8733  [ulSet].
8734  cPropertyIDs
8735  == 0)
8736  {
8737 
8738 dwStatus |=
8739  GETPROP_ALLPROPIDS;
8740 
8741  // We have to
8742  // determine
8743  // if the
8744  // property
8745  // set is
8746  // supported
8747  // and if so
8748  // the count
8749  // of
8750  // properties
8751  // in the
8752  // set.
8753  BOOL
8754  bAvailable =
8755  false;
8756 
8757 for (ULONG l
8758  = 0;
8759  l <
8760  cSelectProps;
8761  l++)
8762  {
8763 
8764 if
8765  (InlineIsEqualGUID
8766  (*ppGuid[l],
8767  rgPropertySets
8768  [ulSet].
8769  guidPropertySet))
8770 
8771  bAvailable
8772  |= true;
8773 }
8774 
8775 
8776 if
8777  (bAvailable
8778  &&
8779 
8780 GetIndexofPropSet
8781  (&
8782  (pPropSet
8783  [iPropSet].
8784  guidPropertySet),
8785  &ulCurSet)
8786  == S_OK)
8787  {
8788 
8789 cProps +=
8790  m_pUPropSet
8791  [ulCurSet].
8792  cUPropInfo;
8793  // Add Enough
8794  // space for
8795  // node that
8796  // are colid
8797  // specific
8798  cProps +=
8799  GetCountofColids
8800  (&m_pUProp
8801  [ulCurSet]);
8802 
8804  (pPropSet
8805  [iPropSet].
8806  guidPropertySet,
8807  dwStatus);
8808 }
8809 
8810  else
8811 
8812  {
8813 
8814  // Not
8815  // Supported
8816  //
8817  dwStatus |=
8818  GETPROP_ERRORSOCCURRED;
8819 
8821  (pPropSet
8822  [iPropSet].
8823  guidPropertySet,
8824  dwStatus);
8825 
8826 goto
8827  NEXT_SET;
8828 }
8829 
8830 }
8831 
8832  else
8833 
8834  {
8835 
8836 cProps =
8837  rgPropertySets
8838  [ulSet].
8839  cPropertyIDs;
8840 
8841  // Check to
8842  // see if
8843  // this is a
8844  // supported
8845  // interface
8846  // based on
8847  // ppGuid.
8848  BOOL
8849  bAvailable =
8850  false;
8851 
8852 for (ULONG l
8853  = 0;
8854  l <
8855  cSelectProps;
8856  l++)
8857  {
8858 
8859 if
8860  (InlineIsEqualGUID
8861  (*ppGuid[l],
8862  rgPropertySets
8863  [ulSet].
8864  guidPropertySet))
8865 
8866  bAvailable
8867  |= true;
8868 }
8869 
8870 
8871 if
8872  (!bAvailable
8873  ||
8874 
8875  (GetIndexofPropSet
8876  (&
8877  (pPropSet
8878  [iPropSet].
8879  guidPropertySet),
8880  &ulCurSet)
8881  != S_OK))
8882  {
8883 
8884 dwStatus |=
8885  GETPROP_NOTSUPPORTED;
8886 
8887 dwStatus |=
8888  GETPROP_ERRORSOCCURRED;
8889 
8890 }
8891 
8892 
8894  (pPropSet
8895  [iPropSet].
8896  guidPropertySet,
8897  dwStatus);
8898 
8899 
8900 }
8901 
8902 }
8903 
8904 
8905 
8906  // Allocate
8907  // DBPROP
8908  // array
8909  if (cProps == 0) // Possible
8910  // with
8911  // Hidden
8912  // Passthrough
8913  // sets
8914  goto NEXT_SET;
8915 
8916 
8917 pProp =
8918  (DBPROP *)
8919  CoTaskMemAlloc
8920  (cProps *
8921  sizeof
8922  (DBPROP));
8923 
8924 if (pProp)
8925  {
8926 
8927  // Initialize
8928  // Buffer
8929  memset (pProp,
8930  0,
8931  cProps
8932  *
8933  sizeof
8934  (DBPROP));
8935 
8936 for (ulProp =
8937  0;
8938  ulProp <
8939  cProps;
8940  ulProp++)
8941 
8942  {
8943 
8944 VariantInit
8945  (&
8946  (pProp
8947  [ulProp].
8948  vValue));
8949 
8950 if (dwStatus
8951  &
8952  GETPROP_NOTSUPPORTED)
8953 
8954  {
8955 
8956  // Not
8957  // supported,
8958  // thus we
8959  // need to
8960  // mark all
8961  // as
8962  // NOT_SUPPORTED
8963  pProp[ulProp].
8964  dwPropertyID =
8965  rgPropertySets
8966  [ulSet].
8967  rgPropertyIDs
8968  [ulProp];
8969 
8970 pProp
8971  [ulProp].
8972  dwStatus =
8973  DBPROPSTATUS_NOTSUPPORTED;
8974 
8976  (pProp
8977  [ulProp].
8978  dwPropertyID,
8979  pProp
8980  [ulProp].
8981  dwStatus);
8982 }
8983 
8984 }
8985 
8986  // Make sure
8987  // we support
8988  // the
8989  // property
8990  // set
8991  if (dwStatus &
8992  GETPROP_NOTSUPPORTED)
8993 
8994  {
8995 
8996 ulNext =
8997  cProps;
8998 
8999 goto
9000  NEXT_SET;
9001 }
9002 
9003 
9004  // Now that
9005  // we have
9006  // determined
9007  // we can
9008  // support
9009  // the
9010  // property
9011  // set, we
9012  // need to
9013  // gather
9014  // current
9015  // property
9016  // values
9017  for (ulProp =
9018  0;
9019  ulProp <
9020  cProps;
9021  ulProp++)
9022 
9023  {
9024 
9025 pCurProp =
9026  &(pProp
9027  [ulNext]);
9028 
9029 
9030  // Initialize
9031  // Variant
9032  // Value
9033  pCurProp->
9034  dwStatus =
9035  DBPROPSTATUS_OK;
9036 
9037 
9038  // Retrieve
9039  // current
9040  // value of
9041  // properties
9042  if (dwStatus &
9043  GETPROP_ALLPROPIDS)
9044 
9045  {
9046 
9047  // Verify
9048  // property
9049  // is
9050  // supported,
9051  // if not do
9052  // not return
9053  //
9054  if (!TESTBIT
9055  (&
9056  (m_rgdwSupported
9057  [ulCurSet
9058  *
9059  m_cElemPerSupported]),
9060  ulProp))
9061 
9062  continue;
9063 
9064  // If we are
9065  // looking
9066  // for
9067  // properties
9068  // in error,
9069  // then we
9070  // should
9071  // ignore
9072  // all
9073  // that are
9074  // not in
9075  // error.
9076  if ((dwStatus
9077  &
9078  GETPROP_PROPSINERROR)
9079  &&
9080 
9081 !TESTBIT
9082  (&
9083  (m_rgdwPropsInError
9084  [ulCurSet
9085  *
9086  m_cElemPerSupported]),
9087  ulProp))
9088 
9089  continue;
9090 
9091 
9092 pUPropInfo =
9093  &(m_pUPropSet
9094  [ulCurSet].
9095  pUPropInfo
9096  [ulProp]);
9097 
9098 
9099 ATLASSERT
9100  (pUPropInfo);
9101 
9102 
9103 pCurProp->
9104  dwPropertyID =
9105  pUPropInfo->
9106  dwPropId;
9107 
9108 pCurProp->
9109  colid =
9110  DB_NULLID;
9111 
9112  // If the
9113  // property
9114  // is
9115  // WRITEABLE
9116  // or
9117  // CHANGABLE,
9118  // then the
9119  // value
9120  // will
9121  // be gotten
9122  // from the
9123  // UPROPVAL
9124  // array,
9125  // else it
9126  // will be
9127  // derive
9128  // from the
9129  // GetDefaultValue
9130  if
9131  (pUPropInfo->
9132  dwFlags &
9133  (DBPROPFLAGS_WRITE
9134  |
9136 
9137  {
9138 
9139 pUPropVal =
9140  &(m_pUProp
9141  [ulCurSet].
9142 
9143  pUPropVal
9144  [GetUPropValIndex
9145  (ulCurSet,
9146  pCurProp->
9147  dwPropertyID)]);
9148 
9149 ATLASSERT
9150  (pUPropVal);
9151 
9152 
9153  // Check to
9154  // see if
9155  // this
9156  // property
9157  // supports
9158  // column
9159  // level,
9160  // if so,
9161  // dump those
9162  // nodes
9163  if
9164  (pUPropInfo->
9165  dwFlags &
9166  DBPROPFLAGS_COLUMNOK)
9167 
9168  {
9169 
9170 if
9171  (pUPropVal->
9172  pCColumnIds)
9173 
9174  {
9175 
9176 RetrieveColumnIdProps
9177  (pProp,
9178  pUPropVal,
9179  &ulNext);
9180 
9181 continue;
9182 }
9183 
9184 }
9185 
9186 
9187 pCurProp->
9188  dwOptions =
9189  pUPropVal->
9190  dwOption;
9191 
9192 hr =
9193  VariantCopy (&
9194  (pCurProp->
9195  vValue),
9196  &
9197  (pUPropVal->
9198  vValue));
9199 
9200 }
9201 
9202  else
9203 
9204  {
9205 
9206 GetDefaultValue
9207  (ulCurSet,
9208  pUPropInfo->
9209  dwPropId,
9210 
9211 &(pCurProp->
9212  dwOptions),
9213  &(pCurProp->
9214  vValue));
9215 
9216 }
9217 
9218 
9219  // Return all
9220  // Properties
9221  // in Error
9222  // with
9223  // CONFLICT
9224  // status
9225  if (dwStatus &
9226  GETPROP_PROPSINERROR)
9227 
9228  pCurProp->
9229  dwStatus =
9230  DBPROPSTATUS_CONFLICTING;
9231 
9232 
9233 dwStatus |=
9234  GETPROP_VALIDPROP;
9235 
9236 }
9237 
9238  else
9239 
9240  {
9241 
9242  // Process
9243  // Properties
9244  // based on
9245  // Restriction
9246  // array.
9247 
9248 pCurProp->
9249  dwPropertyID =
9250  rgPropertySets
9251  [ulSet].
9252  rgPropertyIDs
9253  [ulProp];
9254 
9255 pCurProp->
9256  colid =
9257  DB_NULLID;
9258 
9259 
9260 if
9261  (GetIndexofPropIdinPropSet
9262  (ulCurSet,
9263  pCurProp->
9264  dwPropertyID,
9265 
9266 &ulCurProp)
9267  == S_OK)
9268  {
9269 
9270  // Supported
9271  pUPropInfo =
9272  &(m_pUPropSet
9273  [ulCurSet].
9274  pUPropInfo
9275  [ulCurProp]);
9276 
9277 ATLASSERT
9278  (pUPropInfo);
9279 
9280 
9281  // If the
9282  // property
9283  // is
9284  // WRITEABLE,
9285  // then the
9286  // value
9287  // will
9288  // be gotten
9289  // from the
9290  // UPROPVAL
9291  // array,
9292  // else it
9293  // will be
9294  // derive
9295  // from the
9296  // GetDefaultValue
9297  if
9298  (pUPropInfo->
9299  dwFlags &
9300  (DBPROPFLAGS_WRITE
9301  |
9303 
9304  {
9305 
9306 pUPropVal =
9307  &(m_pUProp
9308  [ulCurSet].
9309 
9310  pUPropVal
9311  [GetUPropValIndex
9312  (ulCurSet,
9313  pCurProp->
9314  dwPropertyID)]);
9315 
9316 ATLASSERT
9317  (pUPropVal);
9318 
9319 
9320  // Check to
9321  // see if
9322  // this
9323  // property
9324  // supports
9325  // column
9326  // level,
9327  // if so,
9328  // dump those
9329  // nodes
9330  if
9331  (pUPropInfo->
9332  dwFlags &
9333  DBPROPFLAGS_COLUMNOK)
9334 
9335  {
9336 
9337 if
9338  (pUPropVal->
9339  pCColumnIds)
9340 
9341  {
9342 
9343 RetrieveColumnIdProps
9344  (pProp,
9345  pUPropVal,
9346  &ulNext);
9347 
9348 continue;
9349 }
9350 
9351 }
9352 
9353 pCurProp->
9354  dwOptions =
9355  pUPropVal->
9356  dwOption;
9357 
9358 hr =
9359  VariantCopy (&
9360  (pCurProp->
9361  vValue),
9362  &
9363  (pUPropVal->
9364  vValue));
9365 
9366 }
9367 
9368  else
9369 
9370  {
9371 
9372 GetDefaultValue
9373  (ulCurSet,
9374  pUPropInfo->
9375  dwPropId,
9376 
9377 &(pCurProp->
9378  dwOptions),
9379  &(pCurProp->
9380  vValue));
9381 
9382 
9383 }
9384 
9385 
9386 dwStatus |=
9387  GETPROP_VALIDPROP;
9388 
9389 }
9390 
9391  else
9392 
9393  {
9394 
9395  // Not
9396  // Supported
9397  pCurProp->
9398  dwStatus =
9399  DBPROPSTATUS_NOTSUPPORTED;
9400 
9401 dwStatus |=
9402  GETPROP_ERRORSOCCURRED;
9403 
9404 }
9405 
9406 }
9407 
9408 
9410  (pCurProp->
9411  dwPropertyID,
9412  pCurProp->
9413  dwStatus);
9414  // Increment
9415  // return
9416  // nodes
9417  // count
9418  ulNext++;
9419 }
9420 
9421 }
9422 
9423  else
9424 
9425  {
9426 
9427 ATLTRACE
9428  (atlTraceDBProvider,
9429  0,
9430  _T
9431  ("Could not allocate DBPROP array for GetProperties\n"));
9432 
9433 if (pPropSet)
9434 
9435  {
9436 
9437  // Since we
9438  // have no
9439  // properties
9440  // to return,
9441  // then we
9442  // need to
9443  // free
9444  // allocated
9445  // memory and
9446  // return
9447  // 0,NULL
9448  for (ulSet =
9449  0;
9450  ulSet <
9451  cSets;
9452  ulSet++)
9453 
9454  {
9455 
9456  // Need to
9457  // loop
9458  // through
9459  // all the
9460  // VARIANTS
9461  // and clear
9462  // them
9463  for (ulProp =
9464  0;
9465  ulProp <
9466  pPropSet
9467  [ulSet].
9468  cProperties;
9469  ulProp++)
9470 
9471  VariantClear
9472  (&
9473  (pPropSet
9474  [ulSet].
9475  rgProperties
9476  [ulProp].
9477  vValue));
9478 
9479 CoTaskMemFree
9480  (pPropSet
9481  [ulSet].
9482  rgProperties);
9483 
9484 }
9485 
9486 
9487  // Free
9488  // DBPROPSET
9489  CoTaskMemFree
9490  (pPropSet);
9491 }
9492 
9493 *pcProperties
9494  = 0;
9495 
9496 *prgProperties
9497  = NULL;
9498 
9499 return
9500  E_OUTOFMEMORY;
9501 
9502 }
9503 
9504 
9505 NEXT_SET:
9506  // It is
9507  // possible
9508  // that all
9509  // properties
9510  // are not
9511  // supported,
9512  // thus we
9513  // should
9514  // delete
9515  // that
9516  // memory and
9517  // set
9518  // rgProperties
9519  // to NULL
9520  if (ulNext ==
9521  0
9522  && pProp)
9523 
9524  {
9525 
9526 CoTaskMemFree
9527  (pProp);
9528 
9529 pProp = NULL;
9530 
9531 }
9532 
9533 
9534 pPropSet
9535  [iPropSet].
9536  cProperties =
9537  ulNext;
9538 
9539 pPropSet
9540  [iPropSet].
9541  rgProperties =
9542  pProp;
9543 
9544 iPropSet++;
9545 
9546 }
9547 
9548 
9549 *pcProperties
9550  = iPropSet;
9551 
9552 *prgProperties
9553  = pPropSet;
9554 
9555 
9556 piIndex.
9557  Free ();
9558 
9559  // At least
9560  // one propid
9561  // was marked
9562  // as not
9563  // S_OK
9564  if (dwStatus &
9565  GETPROP_ERRORSOCCURRED)
9566 
9567  {
9568 
9569  // If at
9570  // least 1
9571  // property
9572  // was set
9573  if (dwStatus &
9574  GETPROP_VALIDPROP)
9575 
9576  return
9577  DB_S_ERRORSOCCURRED;
9578 
9579  else
9580 
9581  {
9582 
9583  // Do not
9584  // free any
9585  // of the
9586  // memory on
9587  // a DB_E_
9588  return
9589  DB_E_ERRORSOCCURRED;
9590 
9591 }
9592 
9593 }
9594 
9595 
9596 return S_OK;
9597 }
9598 
9599 
9600 ULONG
9601  GetCountofColids
9602  (UPROP *
9603  pUProp)
9604  {
9605 
9606 ULONG cExtra
9607  = 0;
9608 
9609 ATLASSERT
9610  (pUProp);
9611 
9612 for (ULONG ul
9613  = 0;
9614  ul <
9615  pUProp->
9616  cPropIds;
9617  ul++)
9618  {
9619 
9620 if (pUProp->
9621  pUPropVal
9622  [ul].
9623  pCColumnIds)
9624 
9625  cExtra +=
9626  (pUProp->
9627  pUPropVal
9628  [ul].
9629  pCColumnIds)->
9630  GetCountOfPropColids
9631  ();
9632 }
9633 
9634 return
9635  cExtra;
9636 }
9637 
9638 
9639 ULONG
9640  GetUPropValIndex
9641  (ULONG
9642  iCurSet,
9643  DBPROPID
9644  dwPropId)
9645  {
9646 
9647 for (ULONG ul
9648  = 0;
9649  ul <
9650  m_pUProp
9651  [iCurSet].
9652  cPropIds;
9653  ul++)
9654  {
9655 
9656 if ((m_pUProp
9657  [iCurSet].
9658  rgpUPropInfo
9659  [ul])->
9660  dwPropId
9661  ==
9662  dwPropId)
9663 
9664  return ul;
9665 
9666 }
9667 
9668 return 0;
9669 }
9670 
9671 
9672 void
9673  RetrieveColumnIdProps
9674  (DBPROP *
9675  pCurProp,
9676  UPROPVAL *
9677  pUPropVal,
9678  ULONG *
9679  pulNext)
9680  {
9681 
9682  // Reset to
9683  // first
9684  // Node
9685  CColumnIds *
9686  pColIds =
9687  pUPropVal->
9688  pCColumnIds;
9689 
9690 HRESULT hr =
9691  E_FAIL;
9692 
9693 for (size_t i
9694  = 0;
9695  i <
9696  pColIds->
9697  GetCount
9698  ();
9699  i++)
9700  {
9701 
9702 CPropColID
9703  colId;
9704 
9705 hr =
9706  pColIds->
9707  GetValue (i,
9708  &
9709  (pCurProp->
9710  dwOptions),
9711  &
9712  (pCurProp->
9713  colid),
9714  &
9715  (pCurProp->
9716  vValue));
9717 
9718 if (SUCCEEDED
9719  (hr))
9720  pCurProp =
9721  &(pCurProp
9722  [++
9723  (*pulNext)]);
9724 
9725 }
9726 
9727 (*pulNext)++;
9728 }
9729 
9730 
9731  // Check the
9732  // arguments
9733  // for
9734  // Retrieve
9735  // Properties
9736  HRESULT
9737  GetPropertiesArgChk
9738  (const ULONG
9739  cPropertySets,
9740  const
9741  DBPROPIDSET
9742  rgPropertySets
9743  [],
9744 
9745 ULONG *
9746  pcProperties,
9747  DBPROPSET **
9748  prgProperties)
9749 
9750  {
9751 
9752  // Initialize
9753  // values
9754  if
9755  (pcProperties)
9756 
9757  *pcProperties
9758  = 0;
9759 
9760 if
9761  (prgProperties)
9762 
9763  *prgProperties
9764  = NULL;
9765 
9766  // Check
9767  // Arguments
9768  if (((cPropertySets > 0) && !rgPropertySets) || !pcProperties || !prgProperties)
9769  return E_INVALIDARG;
9770 
9771  // New
9772  // argument
9773  // check for
9774  // > 1
9775  // cPropertyIDs
9776  // and NULL
9777  // pointer
9778  // for
9779  // array of
9780  // property
9781  // ids.
9782  for (ULONG ul
9783  = 0;
9784  ul <
9785  cPropertySets;
9786  ul++)
9787  {
9788 
9789 if
9790  (rgPropertySets
9791  [ul].
9792  cPropertyIDs
9793  &&
9794  !
9795  (rgPropertySets
9796  [ul].
9797  rgPropertyIDs))
9798 
9799  return
9800  E_INVALIDARG;
9801 
9802 
9803  // Check for
9804  // propper
9805  // formation
9806  // of
9807  // DBPROPSET_PROPERTIESINERROR
9808  if ((m_dwFlags
9809  &
9811  &&
9812 
9813 rgPropertySets
9814  [ul].
9815  guidPropertySet
9816  ==
9817  DBPROPSET_PROPERTIESINERROR)
9818 
9819  {
9820 
9821 if ((cPropertySets > 1) ||
9822 (rgPropertySets[ul].cPropertyIDs != 0) ||
9823 (rgPropertySets[ul].rgPropertyIDs != NULL))
9824  return E_INVALIDARG;
9825 }
9826 
9827 }
9828 
9829 
9830 return S_OK;
9831 }
9832 
9833 
9835  HRESULT
9836  FInit
9837  (CUtlPropsBase
9838  * pCopyMe =
9839  NULL) = 0;
9840 
9841 };
9842 
9843 
9844 // Implementation Class
9845 template < class T >
9846 class ATL_NO_VTABLE CUtlProps: public
9848 
9849  {
9850 
9851 public:
9852 
9853 CUtlProps
9854  (DWORD dwFlags
9855  = 0)
9856  {
9857 
9858 ClearMemberVars
9859  ();
9860 
9861 m_dwFlags =
9862  dwFlags;
9863 }
9864 
9866 
9867  {
9868 
9869 FreeMemory
9870  ();
9871 }
9872 
9873 void
9875 
9876  {
9877 
9878  // Remove
9879  // Property
9880  // Information
9881  if (m_pUProp)
9882 
9883  {
9884 
9885 for (ULONG
9886  ulPropSet
9887  = 0;
9888  ulPropSet
9889  <
9890  m_cUPropSet;
9891  ulPropSet++)
9892 
9893  {
9894 
9895 UPROPVAL *
9896  pUPropVal =
9897  m_pUProp
9898  [ulPropSet].
9899  pUPropVal;
9900 
9901 for (ULONG
9902  ulPropId
9903  = 0;
9904  ulPropId
9905  <
9906  m_pUProp
9907  [ulPropSet].
9908  cPropIds;
9909  ulPropId++)
9910 
9911  {
9912 
9913 delete
9914  pUPropVal
9915  [ulPropId].
9916  pCColumnIds;
9917 
9918 VariantClear
9919  (&
9920  (pUPropVal
9921  [ulPropId].
9922  vValue));
9923 }
9924 
9925 delete
9926  []m_pUProp
9927  [ulPropSet].
9928  rgpUPropInfo;
9929 
9930 delete
9931  []m_pUProp
9932  [ulPropSet].
9933  pUPropVal;
9934 }
9935 
9936 
9937 }
9938 
9939 
9940 m_pUProp.
9941  Free ();
9942 
9943 m_rgdwSupported.
9944  Free ();
9945 
9946 m_rgdwPropsInError.
9947  Free ();
9948 
9949 m_rgiPropSetDex.
9950  Free ();
9951 
9952 CoTaskMemFree
9953  (m_pUPropSet);
9954 
9955 ClearMemberVars
9956  ();
9957 }
9958 
9959 void
9960  ClearMemberVars
9961  ()
9962  {
9963 
9964 m_cPropSetDex
9965  = 0;
9966 
9967 m_cUPropSet =
9968  0;
9969 
9970 m_cUPropSetHidden
9971  = 0;
9972 
9973 m_pUPropSet =
9974  NULL;
9975 
9976 
9977 m_dwFlags =
9978  0;
9979 
9980 
9981 m_cElemPerSupported
9982  = 0;
9983 }
9984 
9985  // Retrieve
9986  // the
9987  // property
9988  // set
9989  // indexes
9990  // that match
9991  // this
9992  // property
9993  // set.
9994  HRESULT
9995  GetPropertySetIndex
9996  (GUID *
9997  pPropertySet)
9998 
9999  {
10000 
10001 DWORD dwFlag
10002  = 0;
10003 
10004 ULONG ulSet;
10005 
10006 
10007 ATLASSERT
10008  (m_cUPropSet
10009  &&
10010  m_pUPropSet);
10011 
10012 ATLASSERT
10013  (m_rgiPropSetDex);
10014 
10015 ATLASSERT
10016  (pPropertySet);
10017 
10018 
10019 m_cPropSetDex
10020  = 0;
10021 
10022 
10023 if
10024  (*pPropertySet
10025  ==
10026  DBPROPSET_DATASOURCEALL)
10027 
10028  {
10029 
10030 dwFlag =
10031  DBPROPFLAGS_DATASOURCE;
10032 
10033 }
10034 
10035  else
10036  if
10037  (*pPropertySet
10038  ==
10039  DBPROPSET_DATASOURCEINFOALL)
10040 
10041  {
10042 
10043 dwFlag =
10044  DBPROPFLAGS_DATASOURCEINFO;
10045 
10046 }
10047 
10048  else
10049  if
10050  (*pPropertySet
10051  ==
10052  DBPROPSET_ROWSETALL)
10053 
10054  {
10055 
10056 dwFlag =
10057  DBPROPFLAGS_ROWSET;
10058 
10059 }
10060 
10061  else
10062  if
10063  (*pPropertySet
10064  ==
10065  DBPROPSET_DBINITALL)
10066 
10067  {
10068 
10069 dwFlag =
10070  DBPROPFLAGS_DBINIT;
10071 
10072 }
10073 
10074  else
10075  if
10076  (*pPropertySet
10077  ==
10078  DBPROPSET_SESSIONALL)
10079 
10080  {
10081 
10082 dwFlag =
10083  DBPROPFLAGS_SESSION;
10084 
10085 }
10086 
10087  else
10088  if
10089  (*pPropertySet
10090  ==
10091  DBPROPSET_COLUMNALL)
10092 
10093  {
10094 
10095 dwFlag =
10096  DBPROPFLAGS_COLUMN;
10097 
10098 }
10099 
10100  else
10101  if
10102  (*pPropertySet
10103  ==
10104  DBPROPSET_INDEXALL)
10105 
10106  {
10107 
10108 dwFlag =
10109  DBPROPFLAGS_INDEX;
10110 
10111 }
10112 
10113  else
10114  if
10115  (*pPropertySet
10116  ==
10117  DBPROPSET_TABLEALL)
10118 
10119  {
10120 
10121 dwFlag =
10122  DBPROPFLAGS_TABLE;
10123 
10124 }
10125 
10126  else
10127  if
10128  (*pPropertySet
10129  ==
10130  DBPROPSET_TRUSTEEALL)
10131 
10132  {
10133 
10134 dwFlag =
10135  DBPROPFLAGS_TRUSTEE;
10136 
10137 }
10138 
10139  else
10140  if
10141  (*pPropertySet
10142  ==
10143  DBPROPSET_VIEWALL)
10144 
10145  {
10146 
10147 dwFlag =
10148  DBPROPFLAGS_VIEW;
10149 
10150 }
10151 
10152  else // No
10153  // scan
10154  // required,
10155  // just
10156  // look
10157  // for
10158  // match.
10159  {
10160 
10161 for (ulSet =
10162  0;
10163  ulSet <
10164  m_cUPropSet;
10165  ulSet++)
10166 
10167  {
10168 
10169 if (*
10170  (m_pUPropSet
10171  [ulSet].
10172  pPropSet)
10173  ==
10174  *pPropertySet)
10175 
10176  {
10177 
10178 m_rgiPropSetDex
10179  [m_cPropSetDex]
10180  = ulSet;
10181 
10182 m_cPropSetDex++;
10183 
10184 break;
10185 }
10186 
10187 }
10188 
10189 goto EXIT;
10190 }
10191 
10192 
10193  // Scan
10194  // through
10195  // the
10196  // property
10197  // sets
10198  // looking
10199  // for
10200  // matching
10201  // attributes
10202  for (ulSet =
10203  0;
10204  ulSet <
10205  m_cUPropSet;
10206  ulSet++)
10207 
10208  {
10209 
10210 if
10211  (m_pUPropSet
10212  [ulSet].
10213  pUPropInfo
10214  [0].
10215  dwFlags &
10216  dwFlag)
10217  {
10218 
10219 m_rgiPropSetDex
10220  [m_cPropSetDex]
10221  = ulSet;
10222 
10223 m_cPropSetDex++;
10224 
10225 }
10226 
10227 }
10228 
10229 
10230 EXIT:
10231 return
10232  (m_cPropSetDex)
10233  ? S_OK :
10234  S_FALSE;
10235 }
10236 
10237 
10239  HRESULT
10241  (ULONG
10242  iPropSet,
10243  DBPROPID
10244  dwPropId,
10245  DWORD *
10246  pdwOption,
10247  VARIANT *
10248  pVar)
10249  {
10250 
10251 return
10253  (T::
10254  _GetPropSet,
10255  iPropSet,
10256  dwPropId,
10257  pdwOption,
10258  pVar);
10259 }
10260 
10261 
10263  HRESULT
10264  FInit
10266  * pCopyMe =
10267  NULL)
10268  {
10269 
10270 return
10272  (T::
10273  _GetPropSet,
10274  pCopyMe);
10275 }
10276 
10277 HRESULT
10278  FillDefaultValues
10279  (ULONG
10280  ulPropSetTarget
10281  =
10282  ULONG_MAX)
10283  {
10284 
10285 HRESULT hr;
10286 
10287 ULONG
10288  ulPropId;
10289 
10290 ULONG
10291  iPropSet;
10292 
10293 ULONG
10294  iNewDex;
10295 
10296  // Fill in
10297  // all the
10298  // actual
10299  // values.
10300  // Typically
10301  // because we
10302  // now have
10303  // an hdbc
10304  // with which
10305  // to get
10306  // them.
10307  // (Or we no
10308  // longer
10309  // have an
10310  // hdbc, so
10311  // must clear
10312  // them.)
10313  // Note that
10314  // the UPROP
10315  // (with
10316  // values)
10317  // array may
10318  // be a
10319  // subset of
10320  // the
10321  // UPROPINFO
10322  // array.
10323  // Only
10324  // writable
10325  // properties
10326  // are in
10327  // UPROP
10328  // array.
10329 
10330  // Maybe
10331  // restrict
10332  // to a
10333  // single
10334  // PropSet if
10335  // within
10336  // valid
10337  // range
10338  // [0...m_cUPropSet-1].
10339  // Otherwise
10340  // do all
10341  // propsets.
10342  iPropSet =
10343  (ulPropSetTarget
10344  <
10345  m_cUPropSet)
10346  ?
10347  ulPropSetTarget
10348  : 0;
10349 
10350 for (;
10351  iPropSet
10352  <
10353  m_cUPropSet;
10354  iPropSet++)
10355 
10356  {
10357 
10358 iNewDex = 0;
10359 
10360 for (ulPropId
10361  = 0;
10362  ulPropId
10363  <
10364  m_pUPropSet
10365  [iPropSet].
10366  cUPropInfo;
10367  ulPropId++)
10368 
10369  {
10370 
10371 if
10372  (m_pUPropSet
10373  [iPropSet].
10374  pUPropInfo
10375  [ulPropId].
10376  dwFlags &
10377  (DBPROPFLAGS_WRITE
10378  |
10380 
10381  {
10382 
10383  // Initialize
10384  // dwFlags
10385  // element of
10386  // UPropVal
10387  m_pUProp
10388  [iPropSet].
10389  pUPropVal
10390  [iNewDex].
10391  dwFlags = 0;
10392 
10393 
10394  // Don't need
10395  // this since
10396  // SetProperties()
10397  // resets
10398  // these.
10399  // ATLASSERT(
10400  // m_pUProp[iPropSet].pUPropVal[iNewDex].dwOption
10401  // ==
10402  // DBPROPOPTIONS_SETIFCHEAP);
10403  ATLASSERT
10404  (m_pUProp
10405  [iPropSet].
10406  pUPropVal
10407  [iNewDex].
10408  pCColumnIds
10409  == NULL);
10410 
10411 
10412 VariantClear
10413  (&m_pUProp
10414  [iPropSet].
10415  pUPropVal
10416  [iNewDex].
10417  vValue);
10418 
10419 hr =
10421  (
10422 iPropSet,
10423 
10424 m_pUPropSet
10425  [iPropSet].
10426  pUPropInfo
10427  [ulPropId].
10428  dwPropId,
10429 
10430 &m_pUProp
10431  [iPropSet].
10432  pUPropVal
10433  [iNewDex].
10434  dwOption,
10435 
10436 &m_pUProp
10437  [iPropSet].
10438  pUPropVal
10439  [iNewDex].
10440  vValue);
10441 
10442 if (FAILED
10443  (hr))
10444  return hr;
10445 
10446 iNewDex++;
10447 }
10448 
10449 }
10450 
10451 
10452  // We're
10453  // through if
10454  // restricting
10455  // to single
10456  // PropSet.
10457  if
10458  (ulPropSetTarget
10459  <
10460  m_cUPropSet)
10461 
10462  break;
10463 }
10464 
10465 return
10466  NOERROR;
10467 }
10468 
10469 
10470  // Translate
10471  // Rowset
10472  // IIDs to
10473  // PROPSET
10474  // structures
10475  // ready to
10476  // pass to
10477  // SetProperties
10478  HRESULT
10479  ConvertRowsetIIDtoDBPROPSET
10480  (const IID *
10481  piid,
10482  DBPROPSET *
10483  pPropSet)
10484  {
10485 
10486 HRESULT hr =
10487  S_OK;
10488 
10489 DBPROP *
10490  pProp;
10491 
10492 
10493 ATLASSERT
10494  (piid
10495  || pPropSet);
10496 
10497 ATLASSERT ((pPropSet->cProperties == 1) || (pPropSet->rgProperties));
10498 
10499 pProp = &(pPropSet->rgProperties[0]);
10500 
10501 if (InlineIsEqualGUID (*piid, __uuidof (IAccessor)))
10502  pProp->dwPropertyID = DBPROP_IAccessor;
10503  else
10504  if
10505  (InlineIsEqualGUID
10506  (*piid,
10507  __uuidof
10508  (IColumnsInfo)))
10509 
10510  pProp->
10511  dwPropertyID =
10512  DBPROP_IColumnsInfo;
10513 
10514  else
10515  if
10516  (InlineIsEqualGUID
10517  (*piid,
10518  __uuidof
10519  (IRowset)))
10520 
10521  pProp->
10522  dwPropertyID =
10523  DBPROP_IRowset;
10524 
10525  else
10526  if
10527  (InlineIsEqualGUID
10528  (*piid,
10529  __uuidof
10530  (IRowsetInfo)))
10531 
10532  pProp->
10533  dwPropertyID =
10534  DBPROP_IRowsetInfo;
10535 
10536  else
10537  if
10538  (InlineIsEqualGUID
10539  (*piid,
10540  __uuidof
10541  (IRowsetLocate)))
10542 
10543  pProp->
10544  dwPropertyID =
10545  DBPROP_IRowsetLocate;
10546 
10547  else
10548  if
10549  (InlineIsEqualGUID
10550  (*piid,
10551  __uuidof
10552  (IColumnsRowset)))
10553 
10554  pProp->
10555  dwPropertyID =
10556  DBPROP_IColumnsRowset;
10557 
10558  else
10559  if
10560  (InlineIsEqualGUID
10561  (*piid,
10562  __uuidof
10563  (IRowsetResynch)))
10564 
10565  pProp->
10566  dwPropertyID =
10567  DBPROP_IRowsetResynch;
10568 
10569  else
10570  if
10571  (InlineIsEqualGUID
10572  (*piid,
10573  __uuidof
10574  (IRowsetScroll)))
10575 
10576  pProp->
10577  dwPropertyID =
10578  DBPROP_IRowsetScroll;
10579 
10580  else
10581  if
10582  (InlineIsEqualGUID
10583  (*piid,
10584  __uuidof
10585  (IRowsetChange)))
10586 
10587  pProp->
10588  dwPropertyID =
10589  DBPROP_IRowsetChange;
10590 
10591  else
10592  if
10593  (InlineIsEqualGUID
10594  (*piid,
10595  __uuidof
10596  (IRowsetUpdate)))
10597 
10598  pProp->
10599  dwPropertyID =
10600  DBPROP_IRowsetUpdate;
10601 
10602  else
10603  if
10604  (InlineIsEqualGUID
10605  (*piid,
10606  __uuidof
10607  (IRowsetIdentity)))
10608 
10609  pProp->
10610  dwPropertyID =
10611  DBPROP_IRowsetIdentity;
10612 
10613  else
10614  if
10615  (InlineIsEqualGUID
10616  (*piid,
10617  __uuidof
10618  (IConnectionPointContainer)))
10619 
10620  pProp->
10621  dwPropertyID =
10622  DBPROP_IConnectionPointContainer;
10623 
10624  else
10625  if
10626  (InlineIsEqualGUID
10627  (*piid,
10628  __uuidof
10629  (ISupportErrorInfo)))
10630 
10631  pProp->
10632  dwPropertyID =
10633  DBPROP_ISupportErrorInfo;
10634 
10635  else
10636  if
10637  (InlineIsEqualGUID
10638  (*piid,
10639  __uuidof
10640  (IRowsetIndex)))
10641 
10642  pProp->
10643  dwPropertyID =
10644  DBPROP_IRowsetIndex;
10645 
10646 #if( OLEDBVER >= 0x0200 )
10647  else
10648  if
10649  (InlineIsEqualGUID
10650  (*piid,
10651  __uuidof
10652  (IProvideMoniker)))
10653 
10654  pProp->
10655  dwPropertyID =
10656  DBPROP_IProvideMoniker;
10657 
10658  else
10659  if
10660  (InlineIsEqualGUID
10661  (*piid,
10662  __uuidof
10663  (IRowsetNotify)))
10664 
10665  pProp->
10666  dwPropertyID =
10667  DBPROP_IRowsetNotify;
10668 
10669  else
10670  if
10671  (InlineIsEqualGUID
10672  (*piid,
10673  __uuidof
10674  (IReadData)))
10675 
10676  pProp->
10677  dwPropertyID =
10678  DBPROP_IReadData;
10679 
10680  else
10681  if
10682  (InlineIsEqualGUID
10683  (*piid,
10684  __uuidof
10685  (IRowsetExactScroll)))
10686 
10687  pProp->
10688  dwPropertyID =
10689  DBPROP_IRowsetExactScroll;
10690 
10691  else
10692  if
10693  (InlineIsEqualGUID
10694  (*piid,
10695  __uuidof
10696  (IRowsetNextRowset)))
10697 
10698  pProp->
10699  dwPropertyID =
10700  DBPROP_IRowsetNextRowset;
10701 
10702  else
10703  if
10704  (InlineIsEqualGUID
10705  (*piid,
10706  __uuidof
10707  (IRowsetNewRowAfter)))
10708 
10709  pProp->
10710  dwPropertyID =
10711  DBPROP_IRowsetNewRowAfter;
10712 
10713  else
10714  if
10715  (InlineIsEqualGUID
10716  (*piid,
10717  __uuidof
10718  (IRowsetWithParameters)))
10719 
10720  pProp->
10721  dwPropertyID =
10722  DBPROP_IRowsetWithParameters;
10723 
10724  else
10725  if
10726  (InlineIsEqualGUID
10727  (*piid,
10728  __uuidof
10729  (IRowsetFind)))
10730 
10731  pProp->
10732  dwPropertyID =
10733  DBPROP_IRowsetFind;
10734 
10735  else
10736  if
10737  (InlineIsEqualGUID
10738  (*piid,
10739  __uuidof
10740  (IRowsetAsynch)))
10741 
10742  pProp->
10743  dwPropertyID =
10744  DBPROP_IRowsetAsynch;
10745 
10746  else
10747  if
10748  (InlineIsEqualGUID
10749  (*piid,
10750  __uuidof
10751  (IRowsetKeys)))
10752 
10753  pProp->
10754  dwPropertyID =
10755  DBPROP_IRowsetKeys;
10756 
10757  else
10758  if
10759  (InlineIsEqualGUID
10760  (*piid,
10761  __uuidof
10762  (IRowsetWatchAll)))
10763 
10764  pProp->
10765  dwPropertyID =
10766  DBPROP_IRowsetWatchAll;
10767 
10768  else
10769  if
10770  (InlineIsEqualGUID
10771  (*piid,
10772  __uuidof
10773  (IRowsetWatchNotify)))
10774 
10775  pProp->
10776  dwPropertyID =
10777  DBPROP_IRowsetWatchNotify;
10778 
10779  else
10780  if
10781  (InlineIsEqualGUID
10782  (*piid,
10783  __uuidof
10784  (IRowsetWatchRegion)))
10785 
10786  pProp->
10787  dwPropertyID =
10788  DBPROP_IRowsetWatchRegion;
10789 
10790  else
10791  if
10792  (InlineIsEqualGUID
10793  (*piid,
10794  __uuidof
10795  (IRowsetCopyRows)))
10796 
10797  pProp->
10798  dwPropertyID =
10799  DBPROP_IRowsetCopyRows;
10800 
10801 #endif // #if( OLEDBVER >= 0x0200 )
10802  else
10803 
10804 hr = S_FALSE;
10805 
10806  // If the IID
10807  // can be
10808  // mapped to
10809  // a
10810  // DBPROPID,
10811  // the
10812  // we need to
10813  // initialize
10814  // the vValue
10815  // to TRUE
10816  if (hr ==
10817  S_OK)
10818  {
10819 
10820  // Set
10821  // PropertySet
10822  pPropSet->
10823  guidPropertySet
10824  =
10826 
10827 
10828  // Set
10829  // Property
10830  pProp->
10831  dwOptions =
10832  DBPROPOPTIONS_REQUIRED;
10833 
10834 pProp->
10835  dwStatus = 0;
10836 
10837 pProp->
10838  colid =
10839  DB_NULLID;
10840 
10841 
10842 VariantInit
10843  (&
10844  (pProp->
10845  vValue));
10846 
10847 pProp->
10848  vValue.vt =
10849  VT_BOOL;
10850 
10851 V_BOOL (&
10852  (pProp->
10853  vValue))
10854  =
10856 
10857 }
10858 
10859 
10860 return hr;
10861 }
10862 
10863 
10864 
10865 void
10866  SetPropertyInError
10867  (const ULONG
10868  iPropSet,
10869  const ULONG
10870  iPropId)
10871  {
10872 
10873 SETBIT (&
10874  (m_rgdwPropsInError
10875  [iPropSet
10876  *
10877  m_cElemPerSupported]),
10878  iPropId);
10879 
10880 }
10881 
10882 BOOL
10883  IsPropSet
10884  (const GUID *
10885  pguidPropSet,
10886  DBPROPID
10887  dwPropId)
10888  {
10889 
10890 HRESULT hr;
10891 
10892 ULONG
10893  iPropSet;
10894 
10895 ULONG
10896  iPropId;
10897 
10898 VARIANT
10899  vValue;
10900 
10901 DWORD
10902  dwOptions;
10903 
10904 
10905 VariantInit
10906  (&vValue);
10907 
10908 
10909 if
10910  (GetIndexofPropSet
10911  (pguidPropSet,
10912  &iPropSet)
10913  == S_OK)
10914  {
10915 
10916 if
10917  (GetIndexofPropIdinPropSet
10918  (iPropSet,
10919  dwPropId,
10920  &iPropId) ==
10921  S_OK)
10922  {
10923 
10924 if
10925  (m_pUPropSet
10926  [iPropSet].
10927  pUPropInfo
10928  [iPropId].
10929  dwFlags &
10930 
10931  (DBPROPFLAGS_WRITE
10932  |
10934 
10935  {
10936 
10937 ULONG
10938  iPropVal =
10940  (iPropSet,
10941  dwPropId);
10942 
10943 
10944 dwOptions =
10945  m_pUProp
10946  [iPropSet].
10947  pUPropVal
10948  [iPropVal].
10949  dwOption;
10950 
10951 hr =
10952  VariantCopy
10953  (&vValue,
10954  &(m_pUProp
10955  [iPropSet].
10956 
10957  pUPropVal
10958  [iPropVal].
10959  vValue));
10960 
10961 }
10962 
10963  else
10964 
10965  {
10966 
10967 hr =
10969  (iPropSet,
10970  dwPropId,
10971 
10972 &dwOptions,
10973  &vValue);
10974 }
10975 
10976 
10977 if
10978  (dwOptions ==
10979  DBPROPOPTIONS_REQUIRED)
10980 
10981  {
10982 
10983 ATLASSERT
10984  (vValue.vt ==
10985  VT_BOOL);
10986 
10987 if (SUCCEEDED
10988  (hr)
10989  &&
10990 
10991 (V_BOOL
10992  (&vValue)
10993  !=
10995 
10996  {
10997 
10998 VariantClear
10999  (&vValue);
11000 
11001 return TRUE;
11002 
11003 }
11004 
11005 }
11006 
11007 }
11008 
11009 }
11010 
11011 
11012 VariantClear
11013  (&vValue);
11014 
11015 return FALSE;
11016 
11017 }
11018 
11020  HRESULT
11021  GetPropValue
11022  (const GUID *
11023  pguidPropSet,
11024  DBPROPID
11025  dwPropId,
11026  VARIANT *
11027  pvValue)
11028  {
11029 
11030 HRESULT hr =
11031  E_FAIL;
11032 
11033 ULONG
11034  iPropSet;
11035 
11036 ULONG
11037  iPropId;
11038 
11039 DWORD
11040  dwOptions;
11041 
11042 CComCritSecLock
11043  <
11044  CComAutoCriticalSection
11045  >
11046  lock
11047  (m_oCriticalSection);
11048 
11049 
11050 if
11051  (GetIndexofPropSet
11052  (pguidPropSet,
11053  &iPropSet)
11054  == S_OK)
11055  {
11056 
11057 if
11058  (GetIndexofPropIdinPropSet
11059  (iPropSet,
11060  dwPropId,
11061  &iPropId) ==
11062  S_OK)
11063  {
11064 
11065 if
11066  (m_pUPropSet
11067  [iPropSet].
11068  pUPropInfo
11069  [iPropId].
11070  dwFlags &
11071  (DBPROPFLAGS_WRITE
11072  |
11074 
11075  {
11076 
11077 hr =
11078  VariantCopy
11079  (pvValue,
11080  &(m_pUProp
11081  [iPropSet].
11082  pUPropVal
11083  [
11084 GetUPropValIndex
11085  (iPropSet,
11086  dwPropId)].
11087  vValue));
11088 
11089 }
11090 
11091  else
11092 
11093  {
11094 
11095 VariantClear
11096  (pvValue);
11097 
11098 
11099 hr =
11101  (iPropSet,
11102  dwPropId,
11103 
11104 &dwOptions,
11105  pvValue);
11106 }
11107 
11108 }
11109 
11110 }
11111 
11112 
11113 return hr;
11114 }
11115 
11116 HRESULT
11117  SetPropValue
11118  (const GUID *
11119  pguidPropSet,
11120  DBPROPID
11121  dwPropId,
11122  VARIANT *
11123  pvValue)
11124  {
11125 
11126 HRESULT hr =
11127  E_FAIL;
11128 
11129 ULONG
11130  iPropSet;
11131 
11132 ULONG
11133  iPropId;
11134 
11135 CComCritSecLock
11136  <
11137  CComAutoCriticalSection
11138  >
11139  lock
11140  (m_oCriticalSection);
11141 
11142 
11143 if
11144  (GetIndexofPropSet
11145  (pguidPropSet,
11146  &iPropSet)
11147  == S_OK)
11148  {
11149 
11150 if
11151  (GetIndexofPropIdinPropSet
11152  (iPropSet,
11153  dwPropId,
11154  &iPropId) ==
11155  S_OK)
11156  {
11157 
11158 ATLASSERT
11159  (m_pUPropSet
11160  [iPropSet].
11161  pUPropInfo
11162  [iPropId].
11163  dwFlags &
11164  (DBPROPFLAGS_WRITE
11165  |
11167 
11168 
11169 hr =
11170  VariantCopy (&
11171  (m_pUProp
11172  [iPropSet].
11173  pUPropVal
11174  [
11175 GetUPropValIndex
11176  (iPropSet,
11177  dwPropId)].
11178  vValue),
11179  pvValue);
11180 
11181 }
11182 
11183 }
11184 
11185 
11186 return hr;
11187 }
11188 
11189 
11190 
11191  // Pointer to
11192  // properties
11193  // in error
11194  // mask
11195  DWORD *
11196  GetPropsInErrorPtr
11197  ()
11198  {
11199  return
11201 
11202 ULONG
11203  GetUPropSetCount
11204  ()
11205  {
11206  return
11207  m_cUPropSet;}
11208 
11209 void
11210  SetUPropSetCount
11211  (ULONG c)
11212  {
11213  m_cUPropSet =
11214  c;}
11215 
11216  // NOTE: The
11217  // following
11218  // functions
11219  // depend on
11220  // all prior
11221  // properties
11222  // in the
11223  // array
11224  // being
11225  // writable.
11226  // This is
11227  // because
11228  // the UPROP
11229  // array
11230  // contains
11231  // only
11232  // writable
11233  // elements,
11234  // and the
11235  // UPROPINFO
11236  // array
11237  // contains
11238  // writable
11239  // and
11240  // read-only
11241  // elements.
11242  // (If this
11243  // is a
11244  // problem,
11245  // we would
11246  // need to
11247  // define
11248  // which one
11249  // it came
11250  // from
11251  // and add
11252  // the
11253  // appropriate
11254  // ATLASSERTs...)
11255 
11256  // Get
11257  // DBPROPOPTIONS_xx
11258  DWORD
11259  GetPropOption
11260  (ULONG
11261  iPropSet,
11262  ULONG iProp)
11263 
11264  {
11265 
11266 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11267 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11268 return m_pUProp[iPropSet].pUPropVal[iProp].dwOption;
11269 }
11270 
11271  // Set
11272  // DBPROPOPTIONS_xx
11273  void
11274  SetPropOption
11275  (ULONG
11276  iPropSet,
11277  ULONG iProp,
11278  DWORD
11279  dwOption)
11280  {
11281 
11282 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11283 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11284 m_pUProp[iPropSet].pUPropVal[iProp].dwOption = dwOption;
11285 }
11286  // Determine
11287  // if
11288  // property
11289  // is
11290  // required
11291  // and
11292  // variant_true
11293  BOOL
11294  IsRequiredTrue
11295  (ULONG
11296  iPropSet,
11297  ULONG iProp)
11298 
11299  {
11300 
11301 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11302 ATLASSERT (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
11303 
11304 return ((m_pUProp[iPropSet].pUPropVal[iProp].dwOption == DBPROPOPTIONS_REQUIRED) &&
11305 (V_BOOL (&m_pUProp[iPropSet].pUPropVal[iProp].vValue) != ATL_VARIANT_FALSE));
11306 }
11307 
11308 DWORD
11309  GetInternalFlags
11310  (ULONG
11311  iPropSet,
11312  ULONG iProp)
11313 
11314  {
11315 
11316 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11317 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11318 return m_pUProp[iPropSet].pUPropVal[iProp].dwFlags;
11319 }
11320 
11321 void
11322  AddInternalFlags
11323  (ULONG
11324  iPropSet,
11325  ULONG iProp,
11326  DWORD
11327  dwFlags)
11328  {
11329 
11330 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11331 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11332 m_pUProp[iPropSet].pUPropVal[iProp].dwFlags |= dwFlags;
11333 }
11334 void RemoveInternalFlags (ULONG iPropSet, ULONG iProp, DWORD dwFlags)
11335  {
11336 
11337 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11338 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11339 m_pUProp[iPropSet].pUPropVal[iProp].dwFlags &= ~dwFlags;
11340 }
11341 VARIANT * GetVariant (ULONG iPropSet, ULONG iProp)
11342  {
11343 
11344 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11345 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11346 return &m_pUProp[iPropSet].pUPropVal[iProp].vValue;
11347 }
11348 
11349 HRESULT
11350  SetVariant
11351  (ULONG
11352  iPropSet,
11353  ULONG iProp,
11354  VARIANT *
11355  pv)
11356  {
11357 
11358 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11359  // Does
11360  // VariantClear
11361  // first.
11362  CComCritSecLock
11363  <
11364  CComAutoCriticalSection
11365  >
11366  lock
11367  (m_oCriticalSection);
11368 
11369 return
11370  VariantCopy
11371  (&m_pUProp
11372  [iPropSet].
11373  pUPropVal
11374  [iProp].
11375  vValue, pv);
11376 
11377 }
11378 
11379 void
11380  SetValEmpty
11381  (ULONG
11382  iPropSet,
11383  ULONG iProp)
11384 
11385  {
11386 
11387 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11388 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11389 VariantClear (&m_pUProp[iPropSet].pUPropVal[iProp].vValue);
11390 }
11391 BOOL IsEmpty (ULONG iPropSet, ULONG iProp)
11392  {
11393 
11394 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11395 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11396 return (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_EMPTY);
11397 }
11398 
11399 void
11400  SetValBool
11401  (ULONG
11402  iPropSet,
11403  ULONG iProp,
11404  VARIANT_BOOL
11405  bVal)
11406  {
11407 
11408 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11409 CComCritSecLock < CComAutoCriticalSection > lock (m_oCriticalSection);
11410  // Note that
11411  // we accept
11412  // any "true"
11413  // value.
11414  VariantClear
11415  (&m_pUProp
11416  [iPropSet].
11417  pUPropVal
11418  [iProp].
11419  vValue);
11420 
11421 m_pUProp
11422  [iPropSet].
11423  pUPropVal
11424  [iProp].
11425  vValue.vt =
11426  VT_BOOL;
11427 
11428 V_BOOL
11429  (&m_pUProp
11430  [iPropSet].
11431  pUPropVal
11432  [iProp].
11433  vValue) =
11434  (bVal ?
11436  :
11438 
11439 }
11440 
11441 VARIANT_BOOL
11442  GetValBool
11443  (ULONG
11444  iPropSet,
11445  ULONG iProp)
11446 
11447  {
11448 
11449 CComCritSecLock
11450  <
11451  CComAutoCriticalSection
11452  >
11453  lock
11454  (m_oCriticalSection);
11455 
11456 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11457 ATLASSERT (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BOOL);
11458 return V_BOOL (&m_pUProp[iPropSet].pUPropVal[iProp].vValue);
11459 }
11460 
11461 void
11462  SetValShort
11463  (ULONG
11464  iPropSet,
11465  ULONG iProp,
11466  SHORT iVal)
11467  {
11468 
11469 CComCritSecLock
11470  <
11471  CComAutoCriticalSection
11472  >
11473  lock
11474  (m_oCriticalSection);
11475 
11476 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11477 VariantClear (&m_pUProp[iPropSet].pUPropVal[iProp].vValue);
11478 m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I2;
11479 m_pUProp[iPropSet].pUPropVal[iProp].vValue.iVal = iVal;
11480 }
11481 SHORT GetValShort (ULONG iPropSet, ULONG iProp)
11482  {
11483 
11484 CComCritSecLock
11485  <
11486  CComAutoCriticalSection
11487  >
11488  lock
11489  (m_oCriticalSection);
11490 
11491 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11492 ATLASSERT (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I2);
11493 return m_pUProp[iPropSet].pUPropVal[iProp].vValue.iVal;
11494 }
11495 
11496 void
11497  SetValLong
11498  (ULONG
11499  iPropSet,
11500  ULONG iProp,
11501  LONG lVal)
11502  {
11503 
11504 CComCritSecLock
11505  <
11506  CComAutoCriticalSection
11507  >
11508  lock
11509  (m_oCriticalSection);
11510 
11511 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11512 VariantClear (&m_pUProp[iPropSet].pUPropVal[iProp].vValue);
11513 m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt = VT_I4;
11514 m_pUProp[iPropSet].pUPropVal[iProp].vValue.lVal = lVal;
11515 }
11516 LONG GetValLong (ULONG iPropSet, ULONG iProp)
11517  {
11518 
11519 CComCritSecLock
11520  <
11521  CComAutoCriticalSection
11522  >
11523  lock
11524  (m_oCriticalSection);
11525 
11526 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11527 ATLASSERT (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_I4);
11528 return m_pUProp[iPropSet].pUPropVal[iProp].vValue.lVal;
11529 }
11530 
11531 HRESULT
11532  SetValString
11533  (ULONG
11534  iPropSet,
11535  ULONG iProp,
11536  const WCHAR *
11537  pwsz)
11538  {
11539 
11540 CComCritSecLock
11541  <
11542  CComAutoCriticalSection
11543  >
11544  lock
11545  (m_oCriticalSection);
11546 
11547 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11548 VARIANT * pv = &m_pUProp[iPropSet].pUPropVal[iProp].vValue;
11549 VariantClear (pv);
11550 pv->bstrVal = SysAllocString (pwsz);
11551 if (pv->bstrVal)
11552  pv->vt = VT_BSTR;
11553  else
11554 
11555 return
11556  E_FAIL;
11557 
11558  // See if
11559  // this was
11560  // used for
11561  // non-string
11562  // type.
11563  // Typically
11564  // this is an
11565  // easy way
11566  // to pass
11567  // integer as
11568  // a string.
11569  if
11570  (GetExpectedVarType
11571  (iPropSet,
11572  iProp) ==
11573  VT_BSTR)
11574  return
11575  NOERROR;
11576 
11577 if (pwsz[0]
11578  !=
11579  L'\0')
11580  return
11581  VariantChangeType
11582  (pv, pv, 0,
11583  GetExpectedVarType
11584  (iPropSet,
11585  iProp));
11586 
11587  // Set to "",
11588  // which for
11589  // non-string
11590  // means
11591  // empty.
11592  SysFreeString
11593  (pv->bstrVal);
11594 
11595 pv->vt =
11596  VT_EMPTY;
11597 
11598 return
11599  NOERROR;
11600 }
11601 
11602 const WCHAR *
11603  GetValString
11604  (ULONG
11605  iPropSet,
11606  ULONG iProp)
11607 
11608  {
11609 
11610 CComCritSecLock
11611  <
11612  CComAutoCriticalSection
11613  >
11614  lock
11615  (m_oCriticalSection);
11616 
11617 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11618 ATLASSERT (m_pUProp[iPropSet].pUPropVal[iProp].vValue.vt == VT_BSTR);
11619 return m_pUProp[iPropSet].pUPropVal[iProp].vValue.bstrVal;
11620 }
11621 
11622 const GUID *
11623  GetGuid (ULONG
11624  iPropSet)
11625 
11626  {
11627 
11628 ATLASSERT
11629  (iPropSet <
11630  m_cUPropSet);
11631 
11632 return
11633  m_pUPropSet
11634  [iPropSet].
11635  pPropSet;
11636 }
11637 
11638 DWORD
11639  GetPropID
11640  (ULONG
11641  iPropSet,
11642  ULONG iProp)
11643 
11644  {
11645 
11646 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11647 return m_pUPropSet[iPropSet].pUPropInfo[iProp].dwPropId;
11648 }
11649 
11650 VARTYPE
11651  GetExpectedVarType
11652  (ULONG
11653  iPropSet,
11654  ULONG iProp)
11655 
11656  {
11657 
11658 ATLASSERT (((iPropSet < m_cUPropSet) && (iProp < m_pUPropSet[iPropSet].cUPropInfo) && (iProp < m_pUProp[iPropSet].cPropIds)));
11659 return m_pUPropSet[iPropSet].pUPropInfo[iProp].VarType;
11660 }
11661 
11662 virtual
11663  HRESULT
11665  (const GUID *
11666  pPropSet,
11667  ULONG *
11668  pulCurSet)
11669  {
11670 
11671 ATLASSERT
11672  (pPropSet
11673  &&
11674  pulCurSet);
11675 
11676 
11677 for (ULONG
11678  ul = 0;
11679  ul <
11680  m_cUPropSet;
11681  ul++)
11682  {
11683 
11684 if (*pPropSet
11685  ==
11686  *
11687  (m_pUPropSet
11688  [ul].
11689  pPropSet))
11690 
11691  {
11692 
11693 *pulCurSet =
11694  ul;
11695 
11696 return S_OK;
11697 
11698 }
11699 
11700 }
11701 
11702 return
11703  S_FALSE;
11704 }
11705 
11706 
11707 
11708 virtual HRESULT OnPropertyChanged (ULONG /* iCurSet
11709  */
11710  ,
11711  DBPROP
11712  *
11713  pDBProp)
11714 
11715  {
11716 
11717  // Prevent
11718  // Level 4
11719  // warnings.
11720  pDBProp;
11721 
11722 __if_exists
11723  (T::
11724  CreateAccessor)
11725 
11726  {
11727 
11728 ATLASSERT
11729  (pDBProp !=
11730  NULL);
11731 
11732 DWORD
11733  dwPropertyID =
11734  pDBProp->
11735  dwPropertyID;
11736 
11737 CComVariant
11738  var =
11739  pDBProp->
11740  vValue;
11741 
11742 
11743 switch
11744  (dwPropertyID)
11745 
11746  {
11747 
11748 case DBPROP_IRowsetLocate:
11749 
11750 case DBPROP_LITERALBOOKMARKS:
11751 
11752 case DBPROP_ORDEREDBOOKMARKS:
11753 
11754  {
11755 
11756 CDBPropSet
11757  set
11758  (DBPROPSET_ROWSET);
11759 
11760 CComVariant
11761  newVar;
11762 
11763 bool bVal;
11764 
11765 if (var.
11766  boolVal
11767  ==
11769 
11770  bVal = true;
11771 
11772  else
11773 
11774 bVal = false;
11775 
11776 
11777 newVar =
11778  bVal;
11779 
11780  // Set the
11781  // bookmarks
11782  // property
11783  // as they
11784  // are
11785  // chained.
11786  // We also
11787  // need to
11788  // turn off
11789  // IRowsetLocate
11790  // if we're
11791  // setting
11792  // BOOKMARKS
11793  // to false
11794  // (see
11795  // the
11796  // DBPROP_BOOKMARKS
11797  // case
11798  // statement.
11799  //
11800  if (var.
11801  boolVal ==
11803 
11804  SetPropValue
11805  (&DBPROPSET_ROWSET,
11806  DBPROP_IRowsetLocate,
11807  &newVar);
11808 
11809 
11810 SetPropValue
11811  (&DBPROPSET_ROWSET,
11812  DBPROP_BOOKMARKS,
11813  &newVar);
11814 
11815 // set.AddProperty(DBPROP_BOOKMARKS, newVar);
11816  // If you set
11817  // IRowsetLocate
11818  // to true,
11819  // then the
11820  // rowset
11821  // can
11822  // handle
11823  // backward
11824  // scrolling
11825  if
11826  (dwPropertyID
11827  ==
11828  DBPROP_IRowsetLocate)
11829 
11830 // set.AddProperty(DBPROP_CANSCROLLBACKWARDS, newVar);
11831  SetPropValue
11832  (&DBPROPSET_ROWSET,
11833  DBPROP_CANSCROLLBACKWARDS,
11834  &newVar);
11835 
11836 // const GUID* ppGuid[1];
11837 // ppGuid[0] = &DBPROPSET_ROWSET;
11838 
11839 // return SetProperties(0, 1, &set, 1, ppGuid);
11840  return S_OK;
11841 }
11842 
11843 break;
11844 
11845 case DBPROP_IRowsetScroll:
11846 
11847  {
11848 
11849 CDBPropSet
11850  set
11851  (DBPROPSET_ROWSET);
11852 
11853 
11854 if (var.
11855  boolVal
11856  ==
11858 
11859  {
11860 
11861 set.
11862  AddProperty
11863  (DBPROP_IRowsetLocate,
11864  true);
11865 
11866 set.
11867  AddProperty
11868  (DBPROP_BOOKMARKS,
11869  true);
11870 
11871 set.
11872  AddProperty
11873  (DBPROP_CANSCROLLBACKWARDS,
11874  true);
11875 }
11876 
11877 
11878 const GUID *
11879  ppGuid[1];
11880 
11881 ppGuid[0] =
11883 
11884 
11885 return
11887  (0, 1, &set,
11888  1, ppGuid);
11889 
11890 }
11891 
11892 break;
11893 
11894 case DBPROP_BOOKMARKS:
11895 
11896  {
11897 
11898 if (var.
11899  boolVal
11900  ==
11902 
11903  {
11904 
11905  // Since we
11906  // support
11907  // bookmarks,
11908  // if someone
11909  // sets
11910  // DBPROP_BOOKMARKS
11911  // to
11912  // ATL_VARIANT_FALSE
11913  // and
11914  // DBPROP_IRowsetLocate
11915  // is
11916  // ATL_VARIANT_TRUE,
11917  // then we
11918  // should
11919  // return an
11920  // error.
11921  // This is an
11922  // invalid
11923  // combination
11924  // of
11925  // properties.
11926  CComVariant
11927  locateVar;
11928 
11929 HRESULT hr =
11930  GetPropValue
11931  (&DBPROPSET_ROWSET,
11932 
11933 DBPROP_IRowsetLocate,
11934  &locateVar);
11935 
11936 if (SUCCEEDED
11937  (hr)
11938  &&
11939  locateVar.
11940  boolVal
11941  ==
11943 
11944  {
11945 
11946  // If the
11947  // DBPROP_BOOKMARKS
11948  // is set to
11949  // required,
11950  // return
11951  // DB_E_ERRORSOCCURRED.
11952  // Otherwise,
11953  // set it to
11954  //
11955  // DB_S_ERRORSOCCURRED.
11956  // Note, we
11957  // won't
11958  // reset the
11959  // property
11960  // since
11961  // setting
11962  // IRowsetLocate
11963  // to
11964  // ATL_VARIANT_TRUE
11965  // will
11966  // set
11967  // DBPROP_BOOKMARKS
11968  // to
11969  // ATL_VARIANT_TRUE
11970  pDBProp->
11971  dwStatus =
11972  DBPROPSTATUS_CONFLICTING;
11973 
11974 
11975 if
11976  (pDBProp->
11977  dwOptions ==
11978  DBPROPOPTIONS_REQUIRED)
11979 
11980  return
11981  DB_E_ERRORSOCCURRED;
11982 
11983  else
11984 
11985 return
11986  DB_S_ERRORSOCCURRED;
11987 
11988 }
11989 
11990 }
11991 
11992 }
11993 
11994 break;
11995 
11996  // This code
11997  // should
11998  // only be
11999  // included
12000  // if you are
12001  // a command
12002  // or
12003  // rowset.
12004 case DBPROP_UPDATABILITY:
12005 
12006  {
12007 
12008 if (var.
12009  lVal !=
12010  0)
12011  {
12012 
12013 CComVariant
12014  changeVar;
12015 
12016 HRESULT hr =
12017  GetPropValue
12018  (&DBPROPSET_ROWSET,
12019 
12020 DBPROP_IRowsetChange,
12021  &changeVar);
12022 
12023 if (FAILED
12024  (hr)
12025  ||
12026  changeVar.
12027  boolVal
12028  ==
12030 
12031  {
12032 
12033  // It doesn't
12034  // make sense
12035  // to set
12036  // DBPROP_UPDATABILITY
12037  // if
12038  // DBPROP_IRowsetChange
12039  // is FALSE
12040  // (i.e. no
12041  // updates)
12042  pDBProp->
12043  dwStatus =
12044  DBPROPSTATUS_CONFLICTING;
12045 
12046 
12047 if
12048  (pDBProp->
12049  dwOptions ==
12050  DBPROPOPTIONS_REQUIRED)
12051 
12052  return
12053  DB_E_ERRORSOCCURRED;
12054 
12055  else
12056 
12057 return
12058  DB_S_ERRORSOCCURRED;
12059 
12060 }
12061 
12062 }
12063 
12064 }
12065 
12066 
12067  // Update the
12068  // IAccessor::m_bIsChangeable
12069  // flag as
12070  // necessary
12071 
12072  // Hold off
12073  // on this
12074  // for now,
12075  // it appears
12076  // to be
12077  // causing a
12078  // GPF
12079  // becuase
12080  // we're
12081  // writing
12082  // this off
12083  // the
12084  // session.
12085 // pT->m_bIsChangeable = (var.iVal & DBPROPVAL_UP_INSERT);
12086 break;
12087 
12088 case DBPROP_IRowsetUpdate:
12089 
12090  {
12091 
12092  // Set the
12093  // DBPROP_IRowsetChange
12094  // and
12095  // DBPROP_IRowsetUpdate
12096  // flags.
12097  // Setting
12098  // DBPROP_IRowsetUpdate
12099  // to true
12100  // sets
12101  // DBPROP_IRowsetChange
12102  // to true
12103 
12104 if (var.
12105  boolVal
12106  ==
12108 
12109  {
12110 
12111 CComVariant
12112  changeVar
12113  (true);
12114 
12115 CDBPropSet
12116  set
12117  (DBPROPSET_ROWSET);
12118 
12119 set.
12120  AddProperty
12121  (DBPROP_IRowsetChange,
12122  changeVar);
12123 
12124 
12125 const GUID *
12126  ppGuid[1];
12127 
12128 ppGuid[0] =
12130 
12131 
12132 return
12134  (0, 1, &set,
12135  1, ppGuid);
12136 
12137 }
12138 
12139 }
12140 
12141 break;
12142 
12143 default:
12144 
12145 break;
12146 }
12147 
12148 }
12149 
12150 
12151 return S_OK;
12152 }
12153 
12154 
12155 virtual
12156  HRESULT
12158  ()
12159  {
12160 
12161 return
12163  (T::
12164  _GetPropSet);
12165 
12166 }
12167 
12168 
12169 HRESULT
12170  GetIndexOfPropertyInSet
12171  (const GUID *
12172  pPropSet,
12173  DBPROPID
12174  dwPropertyId,
12175  ULONG *
12176  piCurPropId,
12177  ULONG *
12178  piCurSet)
12179  {
12180 
12181 HRESULT hr =
12183  (pPropSet,
12184  piCurSet);
12185 
12186 if (hr ==
12187  S_FALSE)
12188 
12189  return hr;
12190 
12191 UPROPINFO *
12192  pUPropInfo =
12193  m_pUPropSet
12194  [*piCurSet].
12195  pUPropInfo;
12196 
12197 for (ULONG ul
12198  = 0;
12199  ul <
12200  m_pUPropSet
12201  [*piCurSet].
12202  cUPropInfo;
12203  ul++)
12204  {
12205 
12206 if
12207  (dwPropertyId
12208  ==
12209  pUPropInfo
12210  [ul].
12211  dwPropId)
12212  *piCurPropId =
12213  ul;
12214 
12215 return S_OK;
12216 
12217 }
12218 
12219 
12220 return
12221  S_FALSE;
12222 }
12223 
12224 HRESULT
12225  SetSupportedBit
12226  (const GUID *
12227  pPropSet,
12228  DBPROPID
12229  dwPropertyId)
12230 
12231  {
12232 
12233 ULONG
12234  iCurPropId,
12235  iCurSet;
12236 
12237 
12238 if
12239  (GetIndexOfPropertyInSet
12240  (pPropSet,
12241  dwPropertyId,
12242  &iCurPropId,
12243  &iCurSet) ==
12244  S_OK)
12245  {
12246 
12247 m_rgdwSupported
12248  [iCurSet *
12250  |=
12251  1 <<
12252  iCurPropId;
12253 
12254 return S_OK;
12255 
12256 }
12257 
12258 return
12259  S_FALSE;
12260 }
12261 
12262 
12263 HRESULT
12264  ClearSupportedBit
12265  (const GUID *
12266  pPropSet,
12267  DBPROPID
12268  dwPropertyId)
12269 
12270  {
12271 
12272 ULONG
12273  iCurPropId,
12274  iCurSet;
12275 
12276 
12277 if
12278  (GetIndexOfPropertyInSet
12279  (pPropSet,
12280  dwPropertyId,
12281  &iCurPropId,
12282  &iCurSet) ==
12283  S_OK)
12284  {
12285 
12286 m_rgdwSupported
12287  [iCurSet *
12289  &=
12290  ~(1 <<
12291  iCurPropId);
12292 
12293 return S_OK;
12294 
12295 }
12296 
12297 return
12298  S_FALSE;
12299 }
12300 
12301 
12302 HRESULT
12303  TestSupportedBit
12304  (const GUID *
12305  pPropSet,
12306  DBPROPID
12307  dwPropertyId,
12308  bool & bSet)
12309 
12310  {
12311 
12312 ULONG
12313  iCurPropId,
12314  iCurSet;
12315 
12316 
12317 if
12318  (GetIndexOfPropertyInSet
12319  (pPropSet,
12320  dwPropertyId,
12321  &iCurPropId,
12322  &iCurSet) ==
12323  S_OK)
12324  {
12325 
12326 bSet =
12327  (m_rgdwSupported
12328  [iCurSet *
12330  & (1 <<
12331  iCurPropId))
12332  != 0;
12333 
12334 return S_OK;
12335 
12336 }
12337 
12338 return
12339  S_FALSE;
12340 }
12341 
12342 void
12343  CopyPropsInError
12344  (DWORD *
12345  rgdwSupported)
12346 
12347  {
12348 
12349 memcpy
12350  (rgdwSupported,
12351  m_rgdwPropsInError,
12352  m_cUPropSet *
12353  m_cElemPerSupported
12354  *
12355  sizeof
12356  (DWORD));
12357 }
12358 
12359 };
12360 
12361 
12362 // IDBPropertiesImpl
12363 // IDBProperties <- IUnknown
12364 template < class T >
12365 class ATL_NO_VTABLE IDBPropertiesImpl: public
12366  IDBProperties,
12367  public
12368  CUtlProps <
12369  T >
12370  {
12371 
12372 public:
12373 STDMETHOD
12374  (GetProperties)
12375  (ULONG
12376  cPropertySets,
12377 
12378 const
12379  DBPROPIDSET
12380  rgPropertySets
12381  [],
12382 
12383 ULONG *
12384  pcProperties,
12385 
12386 DBPROPSET **
12387  prgProperties)
12388 
12389  {
12390 
12391 ATLTRACE
12392  (atlTraceDBProvider,
12393  2,
12394  _T
12395  ("IDBPropertiesImpl::GetProperties\n"));
12396 
12397 T * pT =
12398  (T *) this;
12399 
12400  // You can
12401  // get
12402  // PROPERTIESINERROR
12403  // on
12404  // IDBProperties::GetProperties
12405  // so do the
12406  //
12407  // appropriate
12408  // argument
12409  // checking
12410  // for it.
12411  m_dwFlags |=
12413 
12414 HRESULT hr =
12416  (cPropertySets,
12417  rgPropertySets,
12418  pcProperties,
12419  prgProperties);
12420 
12421 if (FAILED
12422  (hr))
12423  return hr;
12424 
12425 
12426 if
12427  (SUCCEEDED
12428  (hr))
12429  {
12430 
12431  // To allow
12432  // user
12433  // defined
12434  // property
12435  // groups,
12436  // we'll scan
12437  // the
12438  // property
12439  // sets.
12440 
12441 ULONG ulPropSets = 0;
12442 ULONG ulPropElems = 0;
12443 ULONG ulPropInits = 0;
12444 UPROPSET * pSetA = NULL;
12445 UPROPSET * pSetTemp = NULL;
12446 ULONG l = 0;
12447 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
12448 
12449 CTempBuffer < UPROPSET > tmpBuffer;
12450 pSetA = tmpBuffer.Allocate (cSets);
12451 if (pSetA == NULL)
12452  return E_OUTOFMEMORY; // We
12453  // shouldn't
12454  // get
12455  // this
12456  // but...
12457  pSetTemp =
12458  pT->
12459  _GetPropSet
12460  (&ulPropSets,
12461  &ulPropElems,
12462  pSetA);
12463 
12464 
12465 typedef
12466  const GUID *
12467  PCGUID;
12468 
12469 
12470 if (pT->
12471  m_dwStatus
12472  &
12474 
12475  {
12476 
12477 for (l = 0;
12478  l <
12479  cSets;
12480  l++)
12481  {
12482 
12483 if (pSetTemp
12484  [l].
12485  bIsChained
12486  !=
12487  true)
12488  ulPropInits++;
12489 
12490 }
12491 
12492 
12493 CTempBuffer
12494  < PCGUID >
12495  tmpBuffer2;
12496 
12497 PCGUID *
12498  ppGuid =
12499  tmpBuffer2.
12500  Allocate
12501  (ulPropInits);
12502 
12503 if (ppGuid ==
12504  NULL)
12505  return
12506  E_OUTOFMEMORY;
12507 
12508 
12509 ulPropInits
12510  = 0;
12511 
12512 for (l = 0;
12513  l <
12514  cSets;
12515  l++)
12516  {
12517 
12518 if (pSetTemp
12519  [l].
12520  bIsChained
12521  !=
12522  true)
12523  ppGuid
12524  [ulPropInits++]
12525  =
12526  pSetTemp[l].
12527  pPropSet;
12528 }
12529 
12530 
12531 hr =
12532  CUtlProps <
12533  T >::
12535  (cPropertySets,
12536  rgPropertySets,
12537 
12538 pcProperties,
12539  prgProperties,
12540  ulPropInits,
12541  ppGuid);
12542 }
12543 
12544  else
12545 
12546  {
12547 
12548  // Only pass
12549  // through
12550  // initialization
12551  // groups
12552  for (l = 0;
12553  l <
12554  cSets;
12555  l++)
12556  {
12557 
12558 if
12559  (IsEqualGUID
12560  (*pSetTemp
12561  [l].
12562  pPropSet,
12563  DBPROPSET_DBINIT)
12564  ||
12565 
12566 pSetTemp[l].
12567  dwFlags &
12568  UPROPSET_USERINIT)
12569 
12570  ulPropInits++;
12571 
12572 }
12573 
12574 CTempBuffer <
12575  PCGUID >
12576  tmpBuffer2;
12577 
12578 PCGUID *
12579  ppGuid =
12580  tmpBuffer2.
12581  Allocate
12582  (ulPropInits);
12583 
12584 if (ppGuid ==
12585  NULL)
12586  return
12587  E_OUTOFMEMORY;
12588 
12589 
12590 ulPropInits
12591  = 0;
12592 
12593 for (l = 0;
12594  l <
12595  cSets;
12596  l++)
12597  {
12598 
12599 if
12600  (IsEqualGUID
12601  (*pSetTemp
12602  [l].
12603  pPropSet,
12604  DBPROPSET_DBINIT)
12605  ||
12606 
12607 pSetTemp[l].
12608  dwFlags &
12609  UPROPSET_USERINIT)
12610 
12611  ppGuid
12612  [ulPropInits++]
12613  =
12614  pSetTemp[l].
12615  pPropSet;
12616 }
12617 
12618 
12619 hr =
12620  CUtlProps <
12621  T >::
12623  (cPropertySets,
12624  rgPropertySets,
12625 
12626 pcProperties,
12627  prgProperties,
12628  ulPropInits,
12629  ppGuid);
12630 }
12631 
12632 }
12633 
12634 
12635 m_dwFlags |=
12637 
12638 return hr;
12639 }
12640 
12641 
12642 STDMETHOD
12643  (GetPropertyInfo)
12644  (ULONG
12645  cPropertySets,
12646 
12647 const
12648  DBPROPIDSET
12649  rgPropertySets
12650  [],
12651 
12652 ULONG *
12653  pcPropertyInfoSets,
12654 
12655 DBPROPINFOSET
12656  **
12657  prgPropertyInfoSets,
12658 
12659 OLECHAR **
12660  ppDescBuffer)
12661 
12662  {
12663 
12664 ATLTRACE
12665  (atlTraceDBProvider,
12666  2,
12667  _T
12668  ("IDBPropertiesImpl::GetPropertyInfo\n"));
12669 
12670 T * pT =
12671  static_cast <
12672  T * >(this);
12673 
12674 T::
12675  ObjectLock
12676  cab (pT);
12677 
12678 
12679 if (pT->
12680  m_pCUtlPropInfo
12681  ==
12682  NULL)
12683  {
12684 
12685  // Go ahead
12686  // and create
12687  // the
12688  // m_pCUtlPropInfo
12689  // but do not
12690  // change
12691  // the
12692  // Initialized
12693  // status of
12694  // the
12695  // provider
12696  // (see
12697  // IDBInitialize::Initialize).
12698  ATLTRACE
12699  (atlTraceDBProvider,
12700  2,
12701  _T
12702  ("m_pCUtlPropInfo == NULL\n"));
12703 
12704 delete pT->
12705  m_pCUtlPropInfo;
12706 
12707 ATLTRY (pT->
12708  m_pCUtlPropInfo
12709  =
12710  new
12711  CUtlPropInfo
12712  < T >
12713  ())
12714  if (pT->
12715  m_pCUtlPropInfo
12716  == NULL)
12717  {
12718 
12719 ATLTRACE
12720  (atlTraceDBProvider,
12721  0,
12722  _T
12723  ("IDBProperties::GetPropertyInfo Error : OOM\n"));
12724 
12725 return
12726  E_OUTOFMEMORY;
12727 
12728 }
12729 
12730 HRESULT hr =
12731  pT->
12732  m_pCUtlPropInfo->
12733  FInit ();
12734 
12735 if (hr !=
12736  S_OK)
12737  {
12738 
12739 delete pT->
12740  m_pCUtlPropInfo;
12741 
12742 pT->
12743  m_pCUtlPropInfo
12744  = NULL;
12745 
12746 return
12747  E_FAIL;
12748 }
12749 
12750 }
12751 
12752 
12753  // Initialize
12754  //
12755  if
12756  (pcPropertyInfoSets)
12757 
12758  *pcPropertyInfoSets
12759  = 0;
12760 
12761 if
12762  (prgPropertyInfoSets)
12763 
12764  *prgPropertyInfoSets
12765  = NULL;
12766 
12767 if
12768  (ppDescBuffer)
12769 
12770  *ppDescBuffer
12771  = NULL;
12772 
12773  // Check
12774  // Arguments
12775  if (((cPropertySets > 0) && !rgPropertySets) ||
12776 !pcPropertyInfoSets || !prgPropertyInfoSets)
12777  return E_INVALIDARG;
12778 
12779  // New
12780  // argument
12781  // check for
12782  // > 1
12783  // cPropertyIDs
12784  // and NULL
12785  // pointer
12786  // for
12787  // array of
12788  // property
12789  // ids.
12790  const DWORD
12791  SPECIAL_GROUP
12792  = 1;
12793 
12794 const DWORD
12795  SPECIAL_SINGLE
12796  = 2;
12797 
12798 const DWORD
12799  SPECIALS =
12800  SPECIAL_GROUP
12801  |
12802  SPECIAL_SINGLE;
12803 
12804 DWORD
12805  dwSpecial = 0;
12806 
12807 for (ULONG ul
12808  = 0;
12809  ul <
12810  cPropertySets;
12811  ul++)
12812  {
12813 
12814 if ((rgPropertySets[ul].guidPropertySet == DBPROPSET_DATASOURCEALL) ||
12815 (rgPropertySets[ul].guidPropertySet == DBPROPSET_DATASOURCEINFOALL) ||
12816 (rgPropertySets[ul].guidPropertySet == DBPROPSET_DBINITALL) ||
12817 (rgPropertySets[ul].guidPropertySet == DBPROPSET_SESSIONALL) ||
12818 (rgPropertySets[ul].guidPropertySet == DBPROPSET_ROWSETALL) ||
12819 (rgPropertySets[ul].guidPropertySet == DBPROPSET_COLUMNALL) ||
12820 (rgPropertySets[ul].guidPropertySet == DBPROPSET_CONSTRAINTALL) ||
12821 (rgPropertySets[ul].guidPropertySet == DBPROPSET_INDEXALL) ||
12822 (rgPropertySets[ul].guidPropertySet == DBPROPSET_TABLEALL) ||
12823 (rgPropertySets[ul].guidPropertySet == DBPROPSET_TRUSTEEALL) ||
12824 (rgPropertySets[ul].guidPropertySet == DBPROPSET_VIEWALL))
12825  dwSpecial |= SPECIAL_GROUP;
12826  else
12827 
12828 dwSpecial |=
12829  SPECIAL_SINGLE;
12830 
12831 
12832  // Check for
12833  // property
12834  // sets
12835  // containing
12836  // both
12837  // singles
12838  // and
12839  // groups
12840  // Check for
12841  // cPropertyIDs
12842  // != 0 &
12843  // rgPropertyIDs
12844  // == NULL
12845  if ((dwSpecial
12846  ==
12847  SPECIALS)
12848  ||
12849 
12850  (rgPropertySets
12851  [ul].
12852  cPropertyIDs
12853  &&
12854  !
12855  (rgPropertySets
12856  [ul].
12857  rgPropertyIDs)))
12858 
12859  return
12860  E_INVALIDARG;
12861 
12862 }
12863 
12864 
12865 if (pT->
12866  m_dwStatus
12867  &
12869 
12870  return pT->
12871  m_pCUtlPropInfo->
12872  GetPropertyInfo
12873  (cPropertySets,
12874  rgPropertySets,
12875 
12876 pcPropertyInfoSets,
12877  prgPropertyInfoSets,
12878 
12879 ppDescBuffer,
12880  true);
12881  else
12882 
12883 return pT->
12884  m_pCUtlPropInfo->
12885  GetPropertyInfo
12886  (cPropertySets,
12887  rgPropertySets,
12888 
12889 pcPropertyInfoSets,
12890  prgPropertyInfoSets,
12891 
12892 ppDescBuffer,
12893  false,
12894  &DBPROPSET_DBINITALL);
12895 
12896 
12897 }
12898 
12899 
12900 STDMETHOD
12901  (SetProperties)
12902  (ULONG
12903  cPropertySets,
12904 
12905 DBPROPSET
12906  rgPropertySets
12907  [])
12908  {
12909 
12910 ATLTRACE
12911  (atlTraceDBProvider,
12912  2,
12913  _T
12914  ("IDBPropertiesImpl::SetProperties\n"));
12915 
12916 HRESULT hr;
12917 
12918 CAutoVectorPtr
12919  < DBPROPSET >
12920  pdbPropSet;
12921 
12922 ULONG iProp;
12923 
12924 typedef const
12925  GUID * PCGUID;
12926 
12927 T * pT =
12928  static_cast <
12929  T * >(this);
12930 
12931 
12932  // Quick
12933  // return if
12934  // the Count
12935  // of
12936  // Properties
12937  // is 0
12938  if
12939  (cPropertySets
12940  ==
12941  0)
12942  return
12943  S_OK;
12944 
12945  // Determine
12946  // how many
12947  // sets are
12948  // in the
12949  // current
12950  // map
12951  T::ObjectLock lock (pT);
12952 UPROPSET * pSetA = NULL;
12953 UPROPSET * pSetTemp = NULL;
12954 ULONG l = 0;
12955 ULONG ulPropSets = 0;
12956 ULONG ulPropElems = 0;
12957 ULONG ulPropInits = 0;
12958 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
12959 
12960 CTempBuffer < UPROPSET > tmpBuffer;
12961 pSetA = tmpBuffer.Allocate (cSets);
12962 if (pSetA == NULL)
12963  return E_OUTOFMEMORY; // We
12964  // shouldn't
12965  // get
12966  // this
12967  // but...
12968 
12969 pSetTemp =
12970  pT->
12971  _GetPropSet
12972  (&ulPropSets,
12973  &ulPropElems,
12974  pSetA);
12975 
12976 
12977 hr =
12978  CUtlProps <
12979  T >::
12981  (cPropertySets,
12982  rgPropertySets);
12983 
12984 if (SUCCEEDED
12985  (hr))
12986  {
12987 
12988  // We need to
12989  // handle the
12990  // DBINIT
12991  // properties
12992  // specially
12993  // after
12994  // being
12995  // initialized.
12996  // - they
12997  // should be
12998  // treated as
12999  // NOTSETTABLE
13000  // at this
13001  // point.
13002  if (pT->
13003  m_dwStatus
13004  &
13006 
13007  {
13008 
13009 ATLASSERT
13010  (cPropertySets);
13011 
13012 
13013 BOOL
13014  fFoundDBINIT =
13015  FALSE;
13016 
13017  // Allocate a
13018  // DBPROPSET
13019  // structure
13020  // of equal
13021  // size
13022  pdbPropSet.
13023  Allocate
13024  (cPropertySets);
13025 
13026 if
13027  (pdbPropSet ==
13028  NULL)
13029  return
13030  E_OUTOFMEMORY;
13031 
13032 
13033 for (ULONG
13034  iNewSet
13035  =
13036  0,
13037  iSet =
13038  0;
13039  iSet <
13040  cPropertySets;
13041  iSet++)
13042 
13043  {
13044 
13045  // Remove any
13046  // DBPROPSET_DBINIT
13047  // values and
13048  // mark them
13049  // all
13050  // as not
13051  // settable
13052  if ((rgPropertySets[iSet].guidPropertySet == DBPROPSET_DBINIT))
13053  {
13054 
13055 fFoundDBINIT
13056  = TRUE;
13057 
13058 for (iProp =
13059  0;
13060  iProp <
13061  rgPropertySets
13062  [iSet].
13063  cProperties;
13064  iProp++)
13065 
13066  rgPropertySets
13067  [iSet].
13068  rgProperties
13069  [iProp].
13070  dwStatus =
13071  DBPROPSTATUS_NOTSETTABLE;
13072 
13073 }
13074 
13075  else
13076 
13077  {
13078 
13079  // If not
13080  // DBPROPSET_DBINIT
13081  // then copy
13082  // the
13083  // DBPROPSET
13084  // values
13085  pdbPropSet
13086  [iNewSet++] =
13087  rgPropertySets
13088  [iSet];
13089 }
13090 
13091 }
13092 
13093 
13094  // If we have
13095  // no
13096  // propertyset
13097  // to pass on
13098  // to the
13099  // property
13100  // handler,
13101  // we
13102  // can exit
13103  if (iNewSet ==
13104  0)
13105  {
13106 
13107 return
13108  DB_E_ERRORSOCCURRED;
13109 
13110 }
13111 
13112 
13113 for (l = 0;
13114  l <
13115  cSets;
13116  l++)
13117  {
13118 
13119 if (pSetTemp
13120  [l].
13121  bIsChained
13122  !=
13123  true)
13124  ulPropInits++;
13125 
13126 }
13127 
13128 
13129 CTempBuffer
13130  < PCGUID >
13131  tmpBuffer2;
13132 
13133 PCGUID *
13134  ppGuid =
13135  tmpBuffer2.
13136  Allocate
13137  (ulPropInits);
13138 
13139 if (ppGuid ==
13140  NULL)
13141  return
13142  E_OUTOFMEMORY;
13143 
13144 
13145 ulPropInits
13146  = 0;
13147 
13148 for (l = 0;
13149  l <
13150  cSets;
13151  l++)
13152  {
13153 
13154 if (pSetTemp
13155  [l].
13156  bIsChained
13157  !=
13158  true)
13159  ppGuid
13160  [ulPropInits++]
13161  =
13162  pSetTemp[l].
13163  pPropSet;
13164 }
13165 
13166 
13167 hr =
13168  CUtlProps <
13169  T >::
13171  (0, iNewSet,
13172  pdbPropSet,
13173  ulPropInits,
13174  ppGuid);
13175 
13176  // If we have
13177  // determined
13178  // that one
13179  // of the
13180  // property
13181  // sets was
13182  // DBINIT, we
13183  // may
13184  // need to
13185  // fixup the
13186  // returned
13187  // hr value.
13188  if
13189  (fFoundDBINIT
13190  &&
13191  SUCCEEDED
13192  (hr))
13193  hr =
13194  DB_S_ERRORSOCCURRED;
13195 
13196 }
13197 
13198  else
13199 
13200  {
13201 
13202  // Note that
13203  // m_pCUtlProps
13204  // knows
13205  // about
13206  // initialization,
13207  // so we
13208  // don't have
13209  // to here.
13210  // Only pass
13211  // DBPROPSET_DBINIT
13212  // or custom
13213  // initialization
13214  // groups
13215 
13216 for (l = 0;
13217  l <
13218  cSets;
13219  l++)
13220  {
13221 
13222 if
13223  (IsEqualGUID
13224  (*pSetTemp
13225  [l].
13226  pPropSet,
13227  DBPROPSET_DBINIT)
13228  ||
13229 
13230 pSetTemp[l].
13231  dwFlags &
13232  UPROPSET_USERINIT)
13233 
13234  ulPropInits++;
13235 
13236 }
13237 
13238 
13239 CTempBuffer
13240  < PCGUID >
13241  tmpBuffer2;
13242 
13243 PCGUID *
13244  ppGuid =
13245  tmpBuffer2.
13246  Allocate
13247  (ulPropInits);
13248 
13249 if (ppGuid ==
13250  NULL)
13251  return
13252  E_OUTOFMEMORY;
13253 
13254 
13255 ulPropInits
13256  = 0;
13257 
13258 for (l = 0;
13259  l <
13260  cSets;
13261  l++)
13262  {
13263 
13264 if
13265  (IsEqualGUID
13266  (*pSetTemp
13267  [l].
13268  pPropSet,
13269  DBPROPSET_DBINIT)
13270  ||
13271 
13272 pSetTemp[l].
13273  dwFlags &
13274  UPROPSET_USERINIT)
13275 
13276  ppGuid
13277  [ulPropInits++]
13278  =
13279  pSetTemp[l].
13280  pPropSet;
13281 }
13282 
13283 
13284 hr =
13285  CUtlProps <
13286  T >::
13288  (0,
13289  cPropertySets,
13290  rgPropertySets,
13291 
13292 ulPropInits,
13293  ppGuid);
13294 }
13295 
13296 }
13297 
13298 
13299 return hr;
13300 }
13301 
13302 };
13303 
13304 
13305 
13306 #define BEGIN_SCHEMA_MAP(SchemaClass) \
13307  typedef
13308  SchemaClass
13310  \
13311 HRESULT
13313  (GUID **
13314  ppGuid,
13315  \
13316 IUnknown *
13317  pUnkOuter,
13318  \
13319 REFIID
13320  rguidSchema,
13321  \
13322 ULONG
13323  cRestrictions,
13324  \
13325 const
13326  VARIANT
13327  rgRestrictions
13328  [],
13329  \
13330 REFIID
13331  riid,
13332  \
13333 ULONG
13334  cPropertySets,
13335  \
13336 DBPROPSET
13337  rgPropertySets
13338  [],
13339  \
13340 IUnknown **
13341  ppRowset) \
13342  {
13343  \
13344 int cGuids =
13345  0;
13346  \
13347 HRESULT hr =
13348  S_OK;
13349  \
13350 if (ppGuid
13351  !=
13352  NULL)
13353 
13354  *ppGuid =
13355  NULL;
13356 
13357 #define SCHEMA_ENTRY(guid, rowsetClass) \
13358  if (ppGuid !=
13359  NULL
13360  &&
13361  SUCCEEDED
13362  (hr)) \
13363  {
13364  \
13365 cGuids++;
13366  \
13367 *ppGuid =
13368  ATL::
13369  AtlSafeRealloc
13370  < GUID,
13371  ATL::
13372  CComAllocator
13373  > (*ppGuid,
13374  cGuids);
13375  \
13376 hr =
13377  (*ppGuid ==
13378  NULL) ?
13380  : S_OK;
13381  \
13382 if
13383  (SUCCEEDED
13384  (hr))
13385 
13386  (*ppGuid)
13387  [cGuids - 1] =
13388  guid; \
13389  else
13390  \
13391 return hr; \
13392 }
13393  \
13394  else
13395  \
13396  {
13397  \
13398 if
13399  (InlineIsEqualGUID
13400  (guid,
13401  rguidSchema))
13402  \
13403  {
13404  \
13405 rowsetClass
13406  * pRowset;
13407  \
13408 hr =
13409  CheckRestrictions
13410  (rguidSchema,
13411  cRestrictions,
13412  rgRestrictions);
13413  \
13414 if (FAILED
13415  (hr))
13416 
13417  return
13418  E_INVALIDARG;
13419  \
13420 hr =
13421  CreateSchemaRowset
13422  (pUnkOuter,
13423  cRestrictions,
13424  \
13425 rgRestrictions,
13426  riid,
13427  cPropertySets,
13428  \
13429 rgPropertySets,
13430  ppRowset,
13431  pRowset);
13432  \
13433 return hr;
13434  \
13435 }
13436  \
13437 }
13438 
13439 
13440 #define END_SCHEMA_MAP() \
13441  if (ppGuid !=
13442  NULL)
13443 
13444  return hr;
13445  \
13446 return
13447  E_INVALIDARG;
13448  \
13449 }
13450 
13451 
13452 
13453 template < class SessionClass >
13454 class ATL_NO_VTABLE IDBSchemaRowsetImpl: public
13455  IDBSchemaRowset
13456 
13457  {
13458 
13459 public:
13460 
13461 OUT_OF_LINE HRESULT InternalCreateSchemaRowset (IUnknown * pUnkOuter, ULONG /* cRestrictions
13462  */
13463  ,
13464 const VARIANT /* rgRestrictions
13465  */
13466  [], REFIID riid,
13467 
13468 ULONG
13469  cPropertySets,
13470  DBPROPSET
13471  rgPropertySets
13472  [],
13473 
13474 IUnknown
13475  **
13476  ppRowset,
13477  IUnknown
13478  *
13479  pUnkThis,
13481  *
13482  pProps,
13483 
13484 IUnknown
13485  *
13486  pUnkSession)
13487 
13488  {
13489 
13490 ATLTRACE
13491  (atlTraceDBProvider,
13492  2,
13493  _T
13494  ("IDBSchemaRowsetImpl::InternalCreateSchemaRowset\n"));
13495 
13496 
13497 HRESULT hr,
13498  hrProps =
13499  S_OK;
13500 
13501 if (ppRowset
13502  !=
13503  NULL)
13504  *ppRowset =
13505  NULL;
13506 
13507 if ((pUnkOuter != NULL) && !InlineIsEqualUnknown (riid))
13508  return DB_E_NOAGGREGATION;
13509 CComPtr < IUnknown > spUnk;
13510 hr = pUnkThis->QueryInterface (__uuidof (IUnknown), (void **) &spUnk);
13511 if (FAILED (hr))
13512  return hr;
13513 
13514 hr = pProps->FInit ();
13515 if (FAILED (hr))
13516  return hr;
13517 hr = pProps->SetPropertiesArgChk (cPropertySets, rgPropertySets);
13518 if (FAILED (hr))
13519  return hr;
13520 const GUID * ppGuid[1];
13521 ppGuid[0] = &DBPROPSET_ROWSET;
13522 
13523  // Call
13524  // SetProperties.
13525  // The true
13526  // in the
13527  // last
13528  // parameter
13529  // indicates
13530  //
13531  // the
13532  // special
13533  // behavior
13534  // that takes
13535  // place on
13536  // rowset
13537  // creation
13538  // (i.e.
13539  // it
13540  // succeeds
13541  // as long as
13542  // any of the
13543  // properties
13544  // were not
13545  // marked
13546  // as
13547  // DBPROPS_REQUIRED.
13548 
13549 hrProps =
13550  pProps->
13551  SetProperties
13552  (0,
13553  cPropertySets,
13554  rgPropertySets,
13555 
13556 1, ppGuid,
13557  true);
13558 
13559 if (FAILED
13560  (hrProps))
13561 
13562  return
13563  hrProps;
13564 
13565 
13566 CComQIPtr <
13567  IObjectWithSite
13568  > spSite =
13569  spUnk;
13570 
13571 ATLASSERT
13572  (spSite !=
13573  NULL);
13574 
13575 hr =
13576  spSite->
13577  SetSite
13578  (pUnkSession);
13579 
13580 if (FAILED
13581  (hr))
13582  return hr;
13583 
13584 if
13585  (InlineIsEqualGUID
13586  (riid,
13587  IID_NULL))
13588  return
13589  E_NOINTERFACE;
13590 
13591 hr =
13592  spUnk->
13593  QueryInterface
13594  (riid,
13595  (void **)
13596  ppRowset);
13597 
13598 if (FAILED
13599  (hr))
13600  {
13601 
13602 *ppRowset =
13603  NULL;
13604 
13605 return hr;
13606 }
13607 
13608 return
13609  (hrProps ==
13610  DB_S_ERRORSOCCURRED)
13611  ? hrProps :
13612  hr;
13613 }
13614 
13615 
13616 template <
13617  class
13618  SchemaRowsetClass
13619  >
13620 
13621 HRESULT
13622  CreateSchemaRowset
13623  (IUnknown *
13624  pUnkOuter,
13625  ULONG
13626  cRestrictions,
13627 
13628 const
13629  VARIANT
13630  rgRestrictions
13631  [],
13632  REFIID riid,
13633 
13634 ULONG
13635  cPropertySets,
13636  DBPROPSET
13637  rgPropertySets
13638  [],
13639 
13640 IUnknown **
13641  ppRowset,
13642  SchemaRowsetClass
13643  *
13644  &pSchemaRowset)
13645 
13646  {
13647 
13648 ATLTRACE
13649  (atlTraceDBProvider,
13650  2,
13651  _T
13652  ("IDBSchemaRowsetImpl::CreateSchemaRowset\n"));
13653 
13654 
13655 HRESULT
13656  hrProps, hr =
13657  S_OK;
13658 
13659 CComPolyObject
13660  <
13661  SchemaRowsetClass
13662  > *pPolyObj;
13663 
13664 SessionClass
13665  * pT =
13666  (SessionClass
13667  *) this;
13668 
13669 if (FAILED
13670  (hr =
13671  CComPolyObject
13672  <
13673  SchemaRowsetClass
13674  >::
13675  CreateInstance
13676  (pUnkOuter,
13677  &pPolyObj)))
13678 
13679  return hr;
13680 
13681 pSchemaRowset
13682  =
13683  &(pPolyObj->
13684  m_contained);
13685 
13686 CComPtr <
13687  IUnknown >
13688  spOuterUnk;
13689 
13690 (pT->
13691  GetUnknown
13692  ())->
13693  QueryInterface
13694  (__uuidof
13695  (IUnknown),
13696  (void **)
13697  &spOuterUnk);
13698 
13699 SchemaRowsetClass
13700  * myPT =
13701  (SchemaRowsetClass
13702  *)
13703  pSchemaRowset;
13704 
13705 hr =
13706  InternalCreateSchemaRowset
13707  (pUnkOuter,
13708  cRestrictions,
13709  rgRestrictions,
13710 
13711 riid,
13712  cPropertySets,
13713  rgPropertySets,
13714  ppRowset,
13715 
13716 pPolyObj,
13717  myPT,
13718  spOuterUnk);
13719 
13720  // Ref the
13721  // created
13722  // COM object
13723  // and Auto
13724  // release it
13725  // on
13726  // failure
13727  if (FAILED
13728  (hr))
13729  return hr;
13730 
13731 
13732 hrProps =
13733  hr;
13734  // Get a
13735  // pointer to
13736  // the Rowset
13737  // instance
13738  DBROWCOUNT
13739  cRowsAffected;
13740 
13741 hr =
13742  pSchemaRowset->
13743  Execute
13744  (&cRowsAffected,
13745  cRestrictions,
13746  rgRestrictions);
13747 
13748 if (FAILED
13749  (hr))
13750  return hr;
13751 
13752 
13753 
13754 return
13755  (hrProps ==
13756  DB_S_ERRORSOCCURRED)
13757  ? hrProps :
13758  hr;
13759 }
13760 
13761 
13762 
13763 void SetRestrictions (ULONG cRestrictions, GUID * /* rguidSchema
13764  */
13765  ,
13766  ULONG
13767  *
13768  rgRestrictions)
13769 
13770  {
13771 
13772 memset
13773  (rgRestrictions,
13774  0,
13775  sizeof
13776  (ULONG) *
13777  cRestrictions);
13778 
13779 }
13780 
13781 
13782 STDMETHOD
13783  (GetSchemas)
13784  (ULONG *
13785  pcSchemas,
13786  GUID **
13787  prgSchemas,
13788  ULONG **
13789  prgRest)
13790  {
13791 
13792 ATLTRACE
13793  (atlTraceDBProvider,
13794  2,
13795  _T
13796  ("IDBSchemaRowsetImpl::GetSchemas\n"));
13797 
13798 if (pcSchemas
13799  !=
13800  NULL)
13801  *pcSchemas =
13802  0;
13803 
13804 if
13805  (prgSchemas !=
13806  NULL)
13807  *prgSchemas =
13808  NULL;
13809 
13810 if (pcSchemas
13811  == NULL
13812  ||
13813  prgSchemas
13814  ==
13815  NULL)
13816  return
13817  E_INVALIDARG;
13818 
13819 
13820 SessionClass
13821  * pT =
13822  (SessionClass
13823  *) this;
13824 
13825 
13826 HRESULT hr =
13827  pT->
13829  (prgSchemas,
13830  NULL,
13831  GUID_NULL, 0,
13832 
13833 NULL,
13834  GUID_NULL, 0,
13835  NULL, NULL);
13836 
13837 if (FAILED
13838  (hr))
13839  return hr;
13840 
13841 
13842 CComPtr <
13843  IMalloc >
13844  spMalloc;
13845 
13846 hr =
13847  CoGetMalloc
13848  (1,
13849  &spMalloc);
13850 
13851 if (FAILED
13852  (hr))
13853  {
13854 
13855 CoTaskMemFree
13856  (*prgSchemas);
13857 
13858 *prgSchemas =
13859  NULL;
13860 
13861 return hr;
13862 }
13863 
13864 *pcSchemas =
13865  (ULONG)
13866  (spMalloc->
13867  GetSize
13868  (*prgSchemas)
13869  /
13870  sizeof
13871  (GUID));
13872 
13873 
13874 if (prgRest
13875  !=
13876  NULL)
13877  {
13878 
13879  // The OLE DB
13880  // spec
13881  // states
13882  // that if
13883  // prgRest ==
13884  // NULL not
13885  // to return
13886  // array
13887  // but it
13888  // also says
13889  // that is
13890  // E_INVALIDARG,
13891  // so doing
13892  // first
13893  *prgRest =
13894  (ULONG *)
13895  spMalloc->
13896  Alloc (sizeof
13897  (ULONG)
13898  *
13899  (*pcSchemas));
13900 
13901 if (*prgRest
13902  ==
13903  NULL)
13904  {
13905 
13906 spMalloc->
13907  Free
13908  (*prgSchemas);
13909 
13910 *prgSchemas =
13911  NULL;
13912 
13913 return
13914  E_OUTOFMEMORY;
13915 
13916 }
13917 
13918 pT->
13919  SetRestrictions
13920  (*pcSchemas,
13921  *prgSchemas,
13922  *prgRest);
13923 }
13924 
13925 return hr;
13926 }
13927 
13928 STDMETHOD
13929  (GetRowset)
13930  (IUnknown *
13931  pUnkOuter,
13932  REFGUID
13933  rguidSchema,
13934  ULONG
13935  cRestrictions,
13936 
13937 const
13938  VARIANT
13939  rgRestrictions
13940  [],
13941  REFIID riid,
13942  ULONG
13943  cPropertySets,
13944 
13945 DBPROPSET
13946  rgPropertySets
13947  [],
13948  IUnknown **
13949  ppRowset)
13950  {
13951 
13952 ATLTRACE
13953  (atlTraceDBProvider,
13954  2,
13955  _T
13956  ("IDBSchemaRowsetImpl::GetRowset\n"));
13957 
13958 SessionClass
13959  * pT =
13960  (SessionClass
13961  *) this;
13962 
13963  // You must
13964  // specify a
13965  // rowset
13966  // pointer
13967  // per the
13968  // specification
13969  if (ppRowset
13970  == NULL
13971  ||
13972  (cRestrictions
13973  > 0
13974  &&
13975  rgRestrictions
13976  == NULL)
13977  ||
13978 
13979  (cPropertySets
13980  > 0
13981  &&
13982  rgPropertySets
13983  ==
13984  NULL))
13985  return
13986  E_INVALIDARG;
13987 
13988 
13989 if
13990  (rgPropertySets
13991  != NULL)
13992  {
13993 
13994 for (ULONG
13995  ulSet =
13996  0;
13997  ulSet <
13998  cPropertySets;
13999  ulSet++)
14000 
14001  {
14002 
14003 if
14004  (rgPropertySets
14005  [ulSet].
14006  cProperties >
14007  0
14008  &&
14009 
14010 rgPropertySets
14011  [ulSet].
14012  rgProperties
14013  ==
14014  NULL)
14015  return
14016  E_INVALIDARG;
14017 
14018 }
14019 
14020 }
14021 
14022 
14023 return pT->
14025  (NULL,
14026  pUnkOuter,
14027  rguidSchema,
14028  cRestrictions,
14029 
14030 rgRestrictions,
14031  riid,
14032  cPropertySets,
14033 
14034 rgPropertySets,
14035  ppRowset);
14036 
14037 
14038 }
14039 
14040 
14041 HRESULT
14042  CheckRestrictions
14043  (REFGUID
14044  rguidSchema,
14045  ULONG
14046  cRestrictions,
14047 
14048 const
14049  VARIANT
14050  rgRestrictions
14051  [])
14052  {
14053 
14054  // Use this
14055  // function
14056  // to help
14057  // check the
14058  // validity
14059  // of
14060  // restrictions
14061  // against a
14062  // schema
14063  // rowset.
14064  const VARTYPE
14065  rgRestrictionTypes
14066  [3][4] =
14067  {
14068 
14069  {
14070  VT_BSTR, VT_BSTR, VT_BSTR, VT_BSTR}, // DBSCHEMA_TABLES
14071  {
14072  VT_BSTR, VT_BSTR, VT_BSTR, VT_BSTR}, // DBSCHEMA_COLUMNS
14073  {
14074  VT_UI2, VT_BOOL, VT_EMPTY, VT_EMPTY}}; // DBSCHEMA_PROVIDER_TYPES
14075  const ULONG
14076  ulMaxRestrictions
14077  [3] =
14078  {
14079  4, 4, 2};
14080 
14081 
14082 ULONG ulRes
14083  = 0;
14084 
14085 ULONG ulType
14086  = 3;
14087 
14088 
14089 if
14090  (InlineIsEqualGUID
14091  (rguidSchema,
14092  DBSCHEMA_TABLES))
14093 
14094  ulType = 0;
14095 
14096  else
14097  if
14098  (InlineIsEqualGUID
14099  (rguidSchema,
14100  DBSCHEMA_COLUMNS))
14101 
14102  ulType = 1;
14103 
14104  else
14105  if (InlineIsEqualGUID (rguidSchema, DBSCHEMA_PROVIDER_TYPES))
14106  ulType = 2;
14107 
14108 if (ulType < 3) // I.E.
14109  // we
14110  // found
14111  // one
14112  // of
14113  // our
14114  // supported
14115  // rowsets
14116  {
14117 
14118 ULONG
14119  ulCurrentRestrictions
14120  = 0x00;
14121 
14122 ULONG
14123  ulCurrentMask
14124  = 0x01;
14125 
14126  // Ask the
14127  // provider's
14128  // session
14129  // object for
14130  // its list
14131  // of
14132  // restrictions
14133  SessionClass *
14134  pT =
14135  (SessionClass
14136  *) this;
14137 
14138 pT->
14139  SetRestrictions
14140  (1,
14141  (GUID *) &
14142  rguidSchema,
14143  &ulCurrentRestrictions);
14144 
14145 
14146 ATLASSERT
14147  (ulType >= 0
14148  && ulType <
14149  3);
14150  // We allow
14151  // VT_EMPTY
14152  // through in
14153  // case the
14154  // consumer
14155  // wanted to
14156  // ignore
14157  // this
14158  // restriction
14159  // (basically
14160  // a way to
14161  // pass in
14162  // 'NULL').
14163  if
14164  (cRestrictions
14165  >
14166  ulMaxRestrictions
14167  [ulType])
14168  return
14169  E_INVALIDARG;
14170 
14171 
14172 for (ulRes =
14173  0;
14174  ulRes <
14175  cRestrictions;
14176  ulRes++)
14177 
14178  {
14179 
14180  // Check for
14181  // obviously
14182  // invalid
14183  // types
14184  if
14185  (rgRestrictions
14186  [ulRes].vt !=
14187  rgRestrictionTypes
14188  [ulType]
14189  [ulRes]
14190  &&
14191 
14192 rgRestrictions
14193  [ulRes].vt !=
14194  DBTYPE_EMPTY
14195  &&
14196 
14197 rgRestrictions
14198  [ulRes].vt !=
14199  VT_NULL)
14200  return
14201  E_INVALIDARG;
14202 
14203 
14204  // Check for
14205  // restrictions
14206  // the
14207  // provider
14208  // doesn't
14209  // support.
14210  if (!(ulCurrentMask & ulCurrentRestrictions) &&
14211 (rgRestrictions[ulRes].vt != DBTYPE_EMPTY))
14212  return E_INVALIDARG;
14213 
14214 ulCurrentMask <<= 1; // Increase
14215  // mask
14216  // by
14217  // *
14218  // 2;
14219  }
14220 
14221 }
14222 
14223 
14224 return S_OK;
14225 }
14226 
14227 };
14228 
14229 
14230 // IDBCreateCommandImpl
14231 template < class T, class CommandClass >
14232 class ATL_NO_VTABLE IDBCreateCommandImpl: public
14233  IDBCreateCommand
14234 
14235  {
14236 
14237 public:
14238 STDMETHOD
14239  (CreateCommand)
14240  (IUnknown *
14241  pUnkOuter,
14242 
14243 REFIID riid,
14244 
14245 IUnknown **
14246  ppvCommand)
14247  {
14248 
14249 ATLTRACE
14250  (atlTraceDBProvider,
14251  2,
14252  _T
14253  ("IDBCreateCommandImpl::CreateCommand\n"));
14254 
14255 T * pT =
14256  (T *) this;
14257 
14258 
14259 if
14260  (ppvCommand ==
14261  NULL)
14262  return
14263  E_INVALIDARG;
14264 
14265  else
14266 
14267 *ppvCommand =
14268  NULL;
14269 
14270 
14271 HRESULT hr;
14272 
14273 CComPolyObject
14274  <
14275  CommandClass >
14276  *pCommand;
14277 
14278  // You can't
14279  // QI for an
14280  // interface
14281  // other than
14282  // IUnknown
14283  // when
14284  // aggregating
14285  //
14286  // and
14287  // creating
14288  // the
14289  // object.
14290  // You might
14291  // ask for
14292  // your own
14293  // interface,
14294  //
14295  // which
14296  // would be
14297  // bad.
14298  // Note, we
14299  // return
14300  // DB_E_NOAGGREGATION
14301  // instead
14302  // of
14303  // CLASS_E_NOAGGREGATION
14304  // due to OLE
14305  // DB
14306  // constraints.
14307  if (pUnkOuter
14308  != NULL
14309  &&
14310  !InlineIsEqualUnknown
14311  (riid))
14312  return
14313  DB_E_NOAGGREGATION;
14314 
14315 
14316 hr =
14317  CComPolyObject
14318  <
14319  CommandClass
14320  >::
14321  CreateInstance
14322  (pUnkOuter,
14323  &pCommand);
14324 
14325 if (FAILED
14326  (hr))
14327  return hr;
14328  // Ref the
14329  // created
14330  // COM object
14331  // and Auto
14332  // release it
14333  // on
14334  // failure
14335  CComPtr <
14336  IUnknown >
14337  spUnk;
14338 
14339 hr =
14340  pCommand->
14341  QueryInterface
14342  (&spUnk);
14343 
14344 if (FAILED
14345  (hr))
14346  {
14347 
14348 delete pCommand; // must
14349  // hand
14350  // delete
14351  // as
14352  // it
14353  // is
14354  // not
14355  // ref'd
14356  return hr;
14357 }
14358 
14359 ATLASSERT
14360  (pCommand->
14361  m_contained.
14362  m_spUnkSite
14363  == NULL);
14364 
14365 CComPtr <
14366  IUnknown >
14367  spOuterUnk;
14368 
14369 pT->
14370  QueryInterface
14371  (__uuidof
14372  (IUnknown),
14373  (void **)
14374  &spOuterUnk);
14375 
14376 pCommand->
14377  m_contained.
14378  SetSite
14379  (spOuterUnk);
14380 
14381 hr =
14382  pCommand->
14383  QueryInterface
14384  (riid,
14385  (void **)
14386  ppvCommand);
14387 
14388 return hr;
14389 }
14390 
14391 
14392 };
14393 
14394 
14395 
14396 // IGetDataSourceImpl
14397 template < class T >
14398 class ATL_NO_VTABLE IGetDataSourceImpl: public
14399  IGetDataSource
14400 
14401  {
14402 
14403 public:
14404 STDMETHOD
14405  (GetDataSource)
14406  (REFIID riid,
14407 
14408 IUnknown **
14409  ppDataSource)
14410 
14411  {
14412 
14413 ATLTRACE
14414  (atlTraceDBProvider,
14415  2,
14416  _T
14417  ("IGetDataSourceImpl::GetDataSource\n"));
14418 
14419 if
14420  (ppDataSource
14421  ==
14422  NULL)
14423  return
14424  E_INVALIDARG;
14425 
14426 T * pT =
14427  (T *) this;
14428 
14429 ATLASSERT
14430  (pT->
14431  m_spUnkSite
14432  != NULL);
14433 
14434 return pT->
14435  m_spUnkSite->
14436  QueryInterface
14437  (riid,
14438  (void **)
14439  ppDataSource);
14440 
14441 }
14442 };
14443 
14444 
14445 // IOpenRowsetImpl
14446 template < class SessionClass >
14447 class IOpenRowsetImpl: public
14448  IOpenRowset
14449 
14450  {
14451 
14452 public:
14453 template <
14454  class
14455  RowsetClass >
14456 
14457 HRESULT
14458  CreateRowset
14459  (IUnknown *
14460  pUnkOuter,
14461 
14462 DBID *
14463  pTableID,
14464  DBID *
14465  pIndexID,
14466 
14467 REFIID riid,
14468 
14469 ULONG
14470  cPropertySets,
14471  DBPROPSET
14472  rgPropertySets
14473  [],
14474 
14475 IUnknown **
14476  ppRowset,
14477 
14478 RowsetClass
14479  *
14480  &pRowsetObj)
14481 
14482  {
14483 
14484 ATLTRACE
14485  (atlTraceDBProvider,
14486  2,
14487  _T
14488  ("IOpenRowsetImpl::CreateRowset\n"));
14489 
14490 
14491 HRESULT hr,
14492  hrProps =
14493  S_OK;
14494 
14495 if (ppRowset
14496  !=
14497  NULL)
14498  *ppRowset =
14499  NULL;
14500 
14501 if ((pUnkOuter != NULL) && !InlineIsEqualUnknown (riid))
14502  return DB_E_NOAGGREGATION;
14503 CComPolyObject < RowsetClass > *pPolyObj;
14504 if (FAILED (hr = CComPolyObject < RowsetClass >::CreateInstance (pUnkOuter, &pPolyObj)))
14505  return hr;
14506  // Ref the
14507  // created
14508  // COM object
14509  // and Auto
14510  // release it
14511  // on
14512  // failure
14513  CComPtr <
14514  IUnknown >
14515  spUnk;
14516 
14517 hr =
14518  pPolyObj->
14519  QueryInterface
14520  (&spUnk);
14521 
14522 if (FAILED
14523  (hr))
14524  {
14525 
14526 delete pPolyObj; // must
14527  // hand
14528  // delete
14529  // as
14530  // it
14531  // is
14532  // not
14533  // ref'd
14534  return hr;
14535 }
14536 
14537  // Get a
14538  // pointer to
14539  // the Rowset
14540  // instance
14541  pRowsetObj =
14542  &(pPolyObj->
14543  m_contained);
14544 
14545 hr =
14546  pRowsetObj->
14547  FInit ();
14548 
14549 if (FAILED
14550  (hr))
14551  return hr;
14552 
14553 hr =
14554  pRowsetObj->
14555  SetPropertiesArgChk
14556  (cPropertySets,
14557  rgPropertySets);
14558 
14559 if (FAILED
14560  (hr))
14561  return hr;
14562 
14563 
14564 const GUID *
14565  ppGuid[1];
14566 
14567 ppGuid[0] =
14569 
14570 
14571  // Call
14572  // SetProperties.
14573  // The true
14574  // in the
14575  // last
14576  // parameter
14577  // indicates
14578  //
14579  // the
14580  // special
14581  // behavior
14582  // that takes
14583  // place on
14584  // rowset
14585  // creation
14586  // (i.e.
14587  // it
14588  // succeeds
14589  // as long as
14590  // any of the
14591  // properties
14592  // were not
14593  // marked
14594  // as
14595  // DBPROPS_REQUIRED.
14596 
14597 hrProps =
14598  pRowsetObj->
14599  SetProperties
14600  (0,
14601  cPropertySets,
14602  rgPropertySets,
14603 
14604 1, ppGuid,
14605  true);
14606 
14607 if (FAILED
14608  (hrProps))
14609 
14610  return
14611  hrProps;
14612 
14613 CComPtr <
14614  IUnknown >
14615  spOuterUnk;
14616 
14617 ((SessionClass *) this)->QueryInterface (__uuidof (IUnknown), (void **) &spOuterUnk);
14618 pRowsetObj->SetSite (spOuterUnk);
14619 
14620 hr = pRowsetObj->SetCommandText (pTableID, pIndexID);
14621 if (FAILED (hr))
14622  return hr;
14623 DBROWCOUNT cRowsAffected;
14624 
14625  // Check to
14626  // make sure
14627  // we set any
14628  // 'post'
14629  // properties
14630  // based on
14631  // the riid
14632  // requested.
14633  if (FAILED
14634  (pRowsetObj->
14635  OnInterfaceRequested
14636  (riid)))
14637 
14638  return hr;
14639 
14640 
14641 HRESULT
14642  hrExecute;
14643 
14644 if (FAILED
14645  (hrExecute
14646  =
14647  pRowsetObj->
14648  Execute
14649  (NULL,
14650  &cRowsAffected)))
14651 
14652  return
14653  hrExecute;
14654 /*
14655  CComVariant varMaxRows;
14656  if (SUCCEEDED(pRowsetObj->GetPropValue(&DBPROPSET_ROWSET, DBPROP_MAXROWS, &varMaxRows)))
14657  {
14658  if( varMaxRows.lVal > 0 )
14659  {
14660  if( pRowsetObj->m_rgRowData.GetCount() > (size_t)varMaxRows.lVal )
14661  {
14662  pRowsetObj->m_rgRowData.RemoveAt( varMaxRows.lVal,
14663  pRowsetObj->m_rgRowData.GetCount() - varMaxRows.lVal );
14664  }
14665  }
14666  }
14667 */
14668  if
14669  (InlineIsEqualGUID
14670  (riid,
14671  IID_NULL))
14672  {
14673 
14674 return
14675  E_NOINTERFACE;
14676 
14677 }
14678 
14679  else
14680 
14681  {
14682 
14683 if (ppRowset
14684  ==
14685  NULL)
14686  // return
14687  // (hrProps
14688  // ==
14689  // DB_S_ERRORSOCCURRED)
14690  // ?
14691  // DB_E_ERRORSOCCURRED
14692  // : hr;
14693  return
14694  hrProps;
14695 
14696 hr =
14697  pPolyObj->
14698  QueryInterface
14699  (riid,
14700  (void **)
14701  ppRowset);
14702 
14703 
14704 }
14705 
14706 
14707 if (FAILED
14708  (hr))
14709  {
14710 
14711 *ppRowset =
14712  NULL;
14713 
14714 return hr;
14715 }
14716 
14717 
14718 return
14719  (hrProps ==
14720  DB_S_ERRORSOCCURRED
14721  && hrExecute
14722  !=
14723  DB_S_STOPLIMITREACHED)
14724  ? hrProps :
14725  hrExecute;
14726 }
14727 
14728 };
14729 
14730 
14731 // IColumnsInfoImpl
14732 template < class T >
14733 class ATL_NO_VTABLE IColumnsInfoImpl:
14734 public
14735  IColumnsInfo,
14736 
14737 public
14738  CDBIDOps
14739  {
14740 
14741 public:
14742 
14743 HRESULT
14744  CheckCommandText
14745  (IUnknown *
14746  pUnkThis)
14747  {
14748 
14749 HRESULT hr =
14750  E_FAIL;
14751 
14752 CComPtr <
14753  ICommandText >
14754  spText;
14755 
14756 if (SUCCEEDED
14757  (hr =
14758  pUnkThis->
14759  QueryInterface
14760  (__uuidof
14761  (ICommandText),
14762  (void
14763  **)
14764  &spText)))
14765 
14766  {
14767 
14768 LPOLESTR
14769  szCommand;
14770 
14771 hr =
14772  spText->
14773  GetCommandText
14774  (NULL,
14775  &szCommand);
14776 
14777 if (SUCCEEDED
14778  (hr))
14779  CoTaskMemFree
14780  (szCommand);
14781 
14782 }
14783 
14784 return hr;
14785 }
14786 
14788  HRESULT
14789  InternalGetColumnInfo
14790  (DBORDINAL *
14791  pcColumns,
14792  ATLCOLUMNINFO
14793  ** ppInfo)
14794  {
14795 
14796 ATLASSERT
14797  (ppInfo !=
14798  NULL);
14799 
14800 T * pT =
14801  (T *) this;
14802 
14803 if (pT->
14804  CheckCommandText
14805  (pT->
14806  GetUnknown
14807  ()) ==
14808  DB_E_NOCOMMAND)
14809 
14810  return
14811  DB_E_NOCOMMAND;
14812 
14813 *ppInfo =
14814  T::
14815  GetColumnInfo
14816  (pT,
14817  pcColumns);
14818 
14819 return S_OK;
14820 
14821 
14822 }
14823 
14824 STDMETHOD
14825  (GetColumnInfo)
14826  (DBORDINAL *
14827  pcColumns,
14828 
14829 DBCOLUMNINFO
14830  ** prgInfo,
14831 
14832 OLECHAR **
14833  ppStringsBuffer)
14834 
14835  {
14836 
14837 ATLTRACE
14838  (atlTraceDBProvider,
14839  2,
14840  _T
14841  ("IColumnsInfoImpl::GetColumnInfo\n"));
14842 
14843 if (pcColumns
14844  == NULL
14845  ||
14846  prgInfo
14847  == NULL
14848  ||
14849  ppStringsBuffer
14850  ==
14851  NULL)
14852  {
14853 
14854 if (prgInfo
14855  !=
14856  NULL)
14857  *prgInfo =
14858  NULL;
14859 
14860 if
14861  (ppStringsBuffer
14862  !=
14863  NULL)
14864  *ppStringsBuffer
14865  = NULL;
14866 
14867 if (pcColumns
14868  !=
14869  NULL)
14870  *pcColumns =
14871  NULL;
14872 
14873 return
14874  E_INVALIDARG;
14875 
14876 }
14877 
14878 
14879  // NULL out
14880  // pointers
14881  // in case of
14882  // an error
14883  *prgInfo =
14884  NULL;
14885 
14886 *ppStringsBuffer
14887  = NULL;
14888 
14889 *pcColumns =
14890  0;
14891 
14892 
14893 ATLCOLUMNINFO
14894  * pInfo;
14895 
14896 HRESULT hr =
14897  InternalGetColumnInfo
14898  (pcColumns,
14899  &pInfo);
14900 
14901 if (FAILED
14902  (hr))
14903  return hr;
14904 
14905 *prgInfo =
14906  (DBCOLUMNINFO
14907  *)
14908  CoTaskMemAlloc
14909  (*pcColumns *
14910  sizeof
14911  (DBCOLUMNINFO));
14912 
14913 if (*prgInfo
14914  !=
14915  NULL)
14916  {
14917 
14918 size_t
14919  cwRequired;
14920 
14921 DBORDINAL
14922  iCol;
14923 
14924 for (iCol =
14925  0,
14926  cwRequired
14927  = 0;
14928  iCol <
14929  *pcColumns;
14930  iCol++)
14931 
14932  {
14933 
14934 (*prgInfo)
14935  [iCol].
14936  pwszName =
14937  pInfo[iCol].
14938  pwszName;
14939 
14940 (*prgInfo)
14941  [iCol].
14942  pTypeInfo =
14943  pInfo[iCol].
14944  pTypeInfo;
14945 
14946 (*prgInfo)
14947  [iCol].
14948  iOrdinal =
14949  pInfo[iCol].
14950  iOrdinal;
14951 
14952 (*prgInfo)
14953  [iCol].
14954  dwFlags =
14955  pInfo[iCol].
14956  dwFlags;
14957 
14958 (*prgInfo)
14959  [iCol].
14960  ulColumnSize =
14961  pInfo[iCol].
14962  ulColumnSize;
14963 
14964 (*prgInfo)
14965  [iCol].wType =
14966  pInfo[iCol].
14967  wType;
14968 
14969 (*prgInfo)
14970  [iCol].
14971  bPrecision =
14972  pInfo[iCol].
14973  bPrecision;
14974 
14975 (*prgInfo)
14976  [iCol].
14977  bScale =
14978  pInfo[iCol].
14979  bScale;
14980 
14981 (*prgInfo)
14982  [iCol].
14983  columnid =
14984  pInfo[iCol].
14985  columnid;
14986 
14987 
14988 if (pInfo
14989  [iCol].
14990  pwszName)
14991 
14992  {
14993 
14994 cwRequired +=
14995  wcslen (pInfo
14996  [iCol].
14997  pwszName)
14998  + 1;
14999 }
15000 
15001 }
15002 
15003 *ppStringsBuffer
15004  =
15005  (OLECHAR *)
15006  CoTaskMemAlloc
15007  (cwRequired *
15008  sizeof
15009  (OLECHAR));
15010 
15011 if
15012  (*ppStringsBuffer)
15013 
15014  {
15015 
15016 DBORDINAL
15017  iCol;
15018 
15019 size_t
15020  iOffset;
15021 
15022 for (iCol =
15023  0,
15024  iOffset
15025  = 0;
15026  iCol <
15027  *pcColumns;
15028  iCol++)
15029 
15030  {
15031 
15032 if (pInfo
15033  [iCol].
15034  pwszName)
15035 
15036  {
15037 
15038 ocscpy
15039  (*ppStringsBuffer
15040  + iOffset,
15041  pInfo[iCol].
15042  pwszName);
15043 
15044 (*prgInfo)
15045  [iCol].
15046  pwszName =
15047  *ppStringsBuffer
15048  + iOffset;
15049 
15050 if ((pInfo
15051  [iCol].
15052  columnid.
15053  eKind ==
15054  DBKIND_GUID_NAME
15055  ||
15056 
15057 pInfo
15058  [iCol].
15059  columnid.
15060  eKind ==
15061  DBKIND_NAME
15062  ||
15063 
15064 pInfo
15065  [iCol].
15066  columnid.
15067  eKind ==
15069 
15070  {
15071 
15072 (*prgInfo)
15073  [iCol].
15074  columnid.
15075  uName.
15076  pwszName =
15077  *ppStringsBuffer
15078  + iOffset;
15079 }
15080 
15081 iOffset +=
15082  wcslen
15083  (*ppStringsBuffer
15084  + iOffset) +
15085  1;
15086 }
15087 
15088 }
15089 
15090 return S_OK;
15091 }
15092 
15093  else
15094 
15095  {
15096 
15097 ATLTRACE
15098  (atlTraceDBProvider,
15099  0,
15100  _T
15101  ("Failed to allocate string buffer\n"));
15102 
15103 CoTaskMemFree
15104  (*prgInfo);
15105 
15106 *prgInfo =
15107  NULL;
15108 
15109 *pcColumns =
15110  0;
15111 
15112 return
15113  E_OUTOFMEMORY;
15114 
15115 }
15116 
15117 }
15118 
15119  else
15120 
15121  {
15122 
15123 ATLTRACE
15124  (atlTraceDBProvider,
15125  0,
15126  _T
15127  ("Failed to allocate ColumnInfo array\n"));
15128 
15129 *prgInfo =
15130  NULL;
15131 
15132 *pcColumns =
15133  0;
15134 
15135 return
15136  E_OUTOFMEMORY;
15137 
15138 }
15139 
15140 
15141 }
15142 
15143 
15144 STDMETHOD
15145  (MapColumnIDs)
15146  (DBORDINAL
15147  cColumnIDs,
15148 
15149 const DBID
15150  rgColumnIDs
15151  [],
15152 
15153 DBORDINAL
15154  rgColumns[])
15155 
15156  {
15157 
15158 ATLTRACE
15159  (atlTraceDBProvider,
15160  2,
15161  _T
15162  ("IColumnsInfoImpl::MapColumnIDs\n"));
15163 
15164 USES_CONVERSION;
15165 
15166 if ((cColumnIDs != 0 && rgColumnIDs == NULL) || rgColumns == NULL)
15167  return E_INVALIDARG;
15168 DBORDINAL cCols = 0;
15169 DBORDINAL cColsInError = 0;
15170 HRESULT hr = S_OK;
15171 ATLCOLUMNINFO * pInfo;
15172 for (DBORDINAL iColId = 0; iColId < cColumnIDs; iColId++)
15173  {
15174 
15175 hr =
15176  InternalGetColumnInfo
15177  (&cCols,
15178  &pInfo);
15179 
15180 if (hr ==
15181  DB_E_NOCOMMAND)
15182 
15183  return hr;
15184 
15185 DBORDINAL
15186  iColMapCur =
15187  0;
15188 
15189 BOOL bDone =
15190  FALSE;
15191 
15192 while
15193  (iColMapCur <
15194  cCols
15195  && !bDone)
15196  {
15197 
15198 hr =
15199  CompareDBIDs
15200  (&
15201  (pInfo
15202  [iColMapCur].
15203  columnid),
15204  &(rgColumnIDs
15205  [iColId]));
15206 
15207 bDone =
15208  (hr == S_OK
15209  ||
15210  FAILED (hr));
15211 
15212 if (hr ==
15213  S_OK)
15214  rgColumns
15215  [iColId] =
15216  pInfo
15217  [iColMapCur].
15218  iOrdinal;
15219 
15220 iColMapCur++;
15221 
15222 }
15223 
15224 if (!bDone
15225  ||
15226  FAILED
15227  (hr))
15228  {
15229 
15230 rgColumns
15231  [iColId] =
15232  DB_INVALIDCOLUMN;
15233 
15234 cColsInError++;
15235 
15236 }
15237 
15238 
15239 }
15240 
15241 if
15242  (cColsInError
15243  > 0
15244  && cColumnIDs
15245  ==
15246  cColsInError)
15247 
15248  return
15249  DB_E_ERRORSOCCURRED;
15250 
15251 if
15252  (cColsInError
15253  > 0
15254  &&
15255  cColsInError
15256  <
15257  cColumnIDs)
15258  return
15259  DB_S_ERRORSOCCURRED;
15260 
15261 return S_OK;
15262 
15263 }
15264 
15265 };
15266 
15267 
15268 //IConvertTypeImpl
15269 template < class T >
15270 class ATL_NO_VTABLE IConvertTypeImpl: public
15271  IConvertType,
15272  public
15274 
15275  {
15276 
15277 public:
15278 HRESULT
15279  InternalCanConvert
15280  (DBTYPE
15281  wFromType,
15282  DBTYPE
15283  wToType,
15284  DBCONVERTFLAGS
15285  dwConvertFlags,
15286 
15287 bool
15288  bIsCommand,
15289  bool
15290  bHasParamaters,
15291  IObjectWithSite
15292  * pSite)
15293  {
15294 
15295 
15296  // Determine
15297  // if new 2.x
15298  // flags are
15299  // valid
15300  if ((dwConvertFlags & ~(DBCONVERTFLAGS_ISLONG | DBCONVERTFLAGS_ISFIXEDLENGTH | DBCONVERTFLAGS_FROMVARIANT)) != DBCONVERTFLAGS_COLUMN
15301  &&(dwConvertFlags & ~(DBCONVERTFLAGS_ISLONG | DBCONVERTFLAGS_ISFIXEDLENGTH | DBCONVERTFLAGS_FROMVARIANT)) != DBCONVERTFLAGS_PARAMETER)
15302  return DB_E_BADCONVERTFLAG;
15303 
15304  // If the
15305  // convert
15306  // flags are
15307  // for
15308  // DBCONVERTFLAGS_FROMVARIANT,
15309  // check to
15310  // see
15311  // that the
15312  // type is a
15313  // variant
15314  // type
15315  if
15316  (dwConvertFlags
15317  &
15318  DBCONVERTFLAGS_FROMVARIANT)
15319 
15320  {
15321 
15322 if ((wFromType == DBTYPE_BYTES) ||
15323 (wFromType == DBTYPE_STR) ||
15324 (wFromType == DBTYPE_WSTR) ||
15325 (wFromType == DBTYPE_NUMERIC) ||
15326 (wFromType == DBTYPE_UDT) ||
15327 (wFromType == DBTYPE_DBDATE) ||
15328 (wFromType == DBTYPE_DBTIME) ||
15329 (wFromType == DBTYPE_DBTIMESTAMP) ||
15330 (wFromType == DBTYPE_HCHAPTER) ||
15331 (wFromType == DBTYPE_PROPVARIANT) ||
15332 (wFromType == DBTYPE_VARNUMERIC))
15333  return DB_E_BADTYPE;
15334 }
15335 
15336 
15337  // Note, if
15338  // the
15339  // convert
15340  // flag is
15341  // either
15342  // ISLONG or
15343  // ISFIXEDLENGTH,
15344  // then we
15345  // should
15346  // make sure
15347  // we are not
15348  // dealing
15349  // with an
15350  // OLE DB 1.x
15351  // provider.
15352  // However,
15353  // since
15354  // we default
15355  // to 2.x
15356  // providers,
15357  // we don't
15358  // check
15359  // this. If
15360  // you,
15361  // change the
15362  //
15363  // DBPROP_PROVIDEROLEDBVER
15364  // property
15365  // in the
15366  // DATASOURCEINFO
15367  // group, you
15368  // need to
15369  // check the
15370  // property
15371  // value and
15372  // return a
15373  // DB_E_BADCONVERTFLAG
15374  // if it is a
15375  // 1.x
15376  // provider.
15377 
15378  // Do we have
15379  // ISLONG on
15380  // a fixed
15381  // length
15382  // data
15383  // type?
15384  DBTYPE dbtype
15385  =
15386  (DBTYPE)
15387  (wFromType &
15388  ~
15389  (DBTYPE_BYREF
15390  |
15391  DBTYPE_VECTOR
15392  |
15393  DBTYPE_ARRAY
15394  |
15395  DBTYPE_RESERVED));
15396 
15397 if ((dwConvertFlags & DBCONVERTFLAGS_ISLONG) &&
15398 (dbtype != DBTYPE_WSTR && dbtype != DBTYPE_STR && dbtype != DBTYPE_BYTES && dbtype != DBTYPE_VARNUMERIC))
15399  return DB_E_BADCONVERTFLAG;
15400 
15401 DBCONVERTFLAGS dwBaseFlags = (DBCONVERTFLAGS) (dwConvertFlags & ~(DBCONVERTFLAGS_ISLONG | DBCONVERTFLAGS_ISFIXEDLENGTH | DBCONVERTFLAGS_FROMVARIANT));
15402 
15403  // Check if
15404  // this
15405  // should be
15406  // an & or an
15407  // ==
15408  if
15409  (dwBaseFlags
15410  ==
15411  DBCONVERTFLAGS_PARAMETER)
15412 
15413  {
15414 
15415  // In the
15416  // case where
15417  // we are a
15418  // rowset and
15419  // ask for a
15420  // parameter
15421  //
15422  // conversion,
15423  // return
15424  // DB_E_BADCONVERTFLAG
15425  if
15426  (!bIsCommand)
15427 
15428  return
15429  DB_E_BADCONVERTFLAG;
15430 
15431 
15432  // In the
15433  // case where
15434  // we are a
15435  // command
15436  // and ask
15437  // for a
15438  // parameter
15439  //
15440  // conversion
15441  // and
15442  // ICommandWithParameters
15443  // is not
15444  // supported,
15445  // return
15446  // DB_E_BADCONVERTFLAG.
15447  // We used to
15448  // return
15449  // S_FALSE,
15450  // but spec
15451  // says
15452  // return
15453  // DB_E_BADCONVERTFLAG
15454  // if not
15455  // supported.
15456  if
15457  (!bHasParamaters)
15458 
15459  return
15460  DB_E_BADCONVERTFLAG;
15461 
15462 }
15463 
15464 
15465  // If we deal
15466  // with a
15467  // command
15468  // and the
15469  // user asks
15470  // for a
15471  // conversion
15472  // on a
15473  // rowset
15474  // the
15475  // DBPROP_ROWSETCONVERSIONSONCOMMAND
15476  // must be
15477  // supported
15478  // and set to
15479  // TRUE.
15480  if (bIsCommand
15481  &&
15482  (dwBaseFlags
15483  ==
15484  DBCONVERTFLAGS_COLUMN))
15485 
15486  {
15487 
15488 CDBPropIDSet
15489  set
15490  (DBPROPSET_DATASOURCEINFO);
15491 
15492 set.
15493  AddPropertyID
15494  (DBPROP_ROWSETCONVERSIONSONCOMMAND);
15495 
15496 DBPROPSET *
15497  pPropSet =
15498  NULL;
15499 
15500 ULONG
15501  ulPropSet = 0;
15502 
15503 
15504  // Get a
15505  // pointer
15506  // into the
15507  // session
15508  CComPtr <
15509  IGetDataSource
15510  >
15511  spDataSource;
15512 
15513 CComPtr <
15514  IDBProperties
15515  > spProps;
15516 
15517  // if any of
15518  // these
15519  // calls
15520  // fail,
15521  // we're
15522  // either
15523  // unable to
15524  // retrieve
15525  // the
15526  // property
15527  // or it is
15528  // unsupported.
15529  // Since the
15530  // property
15531  // is only
15532  // on
15533  // the data
15534  // source
15535  // object, we
15536  // use the
15537  // IObjectWithSite
15538  // interface
15539  // to
15540  // get the
15541  // session
15542  // object and
15543  // then the
15544  // GetDataSource
15545  // method to
15546  // get
15547  // the data
15548  // source
15549  // object
15550  // itself.
15551  if (FAILED
15552  (pSite->
15553  GetSite
15554  (__uuidof
15555  (IGetDataSource),
15556  (void
15557  **)
15558  &spDataSource)))
15559 
15560  return
15561  DB_E_BADCONVERTFLAG;
15562 
15563 if (FAILED
15564  (spDataSource->
15565  GetDataSource
15566  (__uuidof
15567  (IDBProperties),
15568 
15569  (IUnknown
15570  **) &
15571  spProps)))
15572 
15573  return
15574  DB_E_BADCONVERTFLAG;
15575 
15576 if (FAILED
15577  (spProps->
15578  GetProperties
15579  (1,
15580  &set,
15581  &ulPropSet,
15582  &pPropSet)))
15583 
15584  return
15585  DB_E_BADCONVERTFLAG;
15586 
15587 
15588 if (pPropSet
15589  !=
15590  NULL)
15591  {
15592 
15593 CComVariant
15594  var =
15595  pPropSet->
15596  rgProperties
15597  [0].vValue;
15598 
15599 CoTaskMemFree
15600  (pPropSet->
15601  rgProperties);
15602 
15603 CoTaskMemFree
15604  (pPropSet);
15605 
15606 
15607 if (var.
15608  boolVal
15609  ==
15611 
15612  return
15613  DB_E_BADCONVERTFLAG;
15614 
15615 }
15616 
15617 }
15618 
15619 HRESULT hr =
15620  E_FAIL;
15621 
15622 if
15623  (m_spConvert
15624  != NULL)
15625  {
15626 
15627 hr =
15628  m_spConvert->
15629  CanConvert
15630  (wFromType,
15631  wToType);
15632 
15633 if (hr ==
15634  E_INVALIDARG)
15635 
15636  {
15637 
15638  // Data
15639  // Conversion
15640  // library
15641  // said the
15642  // types
15643  // specified
15644  // were
15645  // invalid
15646  // however,
15647  // in OLE DB
15648  // 2.X, the
15649  // value for
15650  // this
15651  // changed
15652  // from
15653  // E_INVALIDARG
15654  // to
15655  // S_FALSE
15656  hr = S_FALSE;
15657 }
15658 
15659 }
15660 
15661 return hr;
15662 }
15663 
15664 STDMETHOD
15665  (CanConvert)
15666  (DBTYPE
15667  wFromType,
15668  DBTYPE
15669  wToType,
15670  DBCONVERTFLAGS
15671  dwConvertFlags)
15672 
15673  {
15674 
15675 ATLTRACE
15676  (atlTraceDBProvider,
15677  2,
15678  _T
15679  ("IConvertTypeImpl::CanConvert\n"));
15680 
15681 T * pT =
15682  (T *) this;
15683 
15684 return pT->
15685  InternalCanConvert
15686  (wFromType,
15687  wToType,
15688  dwConvertFlags,
15689  pT->
15690  m_bIsCommand,
15691  pT->
15692  m_bHasParamaters,
15693  pT);
15694 }
15695 
15696 };
15697 
15698 
15699 template < class T, class PropClass = T >
15700 class ATL_NO_VTABLE ICommandPropertiesImpl:
15701 public
15702  ICommandProperties,
15703 
15704 public
15705  CUtlProps <
15706  PropClass >
15707  {
15708 
15709 public:
15710 typedef
15711  PropClass
15713 
15714 
15715 STDMETHOD
15716  (GetProperties)
15717  (const ULONG
15718  cPropertyIDSets,
15719 
15720 const
15721  DBPROPIDSET
15722  rgPropertyIDSets
15723  [],
15724 
15725 ULONG *
15726  pcPropertySets,
15727 
15728 DBPROPSET **
15729  prgPropertySets)
15730 
15731  {
15732 
15733 ATLTRACE
15734  (atlTraceDBProvider,
15735  2,
15736  _T
15737  ("ICommandPropertiesImpl::GetProperties\n"));
15738 
15739 
15740 T * pT;
15741 
15742 pT =
15743  static_cast <
15744  T * >(this);
15745 
15746 m_dwFlags |=
15748 
15749 HRESULT hr =
15751  (cPropertyIDSets,
15752  rgPropertyIDSets,
15753  pcPropertySets,
15754  prgPropertySets);
15755 
15756 if (SUCCEEDED
15757  (hr))
15758  {
15759 
15760  // Scan
15761  // property
15762  // sets to
15763  // allow user
15764  // defined
15765  // properies
15766  ULONG ulPropSets = 0;
15767 ULONG ulPropElems = 0;
15768 ULONG ulPropInits = 0;
15769 UPROPSET * pSetA = NULL;
15770 UPROPSET * pSetTemp = NULL;
15771 ULONG l = 0;
15772 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
15773 
15774 CTempBuffer < UPROPSET > tmpBuffer;
15775 pSetA = tmpBuffer.Allocate (cSets);
15776 if (pSetA == NULL)
15777  return E_OUTOFMEMORY; // We
15778  // shouldn't
15779  // get
15780  // this
15781  // but...
15782  pSetTemp =
15783  pT->
15784  _GetPropSet
15785  (&ulPropSets,
15786  &ulPropElems,
15787  pSetA);
15788 
15789 
15790 typedef
15791  const GUID *
15792  PCGUID;
15793 
15794 
15795 for (l = 0;
15796  l <
15797  cSets;
15798  l++)
15799  {
15800 
15801 if (pSetTemp
15802  [l].
15803  bIsChained
15804  !=
15805  true)
15806  ulPropInits++;
15807 
15808 }
15809 
15810 
15811 CTempBuffer
15812  < PCGUID >
15813  tmpBuffer2;
15814 
15815 PCGUID *
15816  ppGuid =
15817  tmpBuffer2.
15818  Allocate
15819  (ulPropInits);
15820 
15821 if (ppGuid ==
15822  NULL)
15823  return
15824  E_OUTOFMEMORY;
15825 
15826 ulPropInits =
15827  0;
15828 
15829 for (l = 0;
15830  l <
15831  cSets;
15832  l++)
15833  {
15834 
15835 if (pSetTemp
15836  [l].
15837  bIsChained
15838  !=
15839  true)
15840  ppGuid
15841  [ulPropInits++]
15842  =
15843  pSetTemp[l].
15844  pPropSet;
15845 }
15846 
15847 
15848 hr =
15849  CUtlProps <
15850  PropClass >::
15852  (cPropertyIDSets,
15853 
15854 rgPropertyIDSets,
15855  pcPropertySets,
15856  prgPropertySets,
15857 
15858 ulPropInits,
15859  ppGuid);
15860 }
15861 
15862 m_dwFlags |=
15864 
15865 return hr;
15866 
15867 
15868 }
15869 
15870 
15871 STDMETHOD
15872  (SetProperties)
15873  (ULONG
15874  cPropertySets,
15875 
15876 DBPROPSET
15877  rgPropertySets
15878  [])
15879  {
15880 
15881 ATLTRACE (atlTraceDBProvider, 2, _T ("ICommandPropertiesImpl::SetProperties\n"));
15882 T * pT = (T *) this;
15883 
15884 if (pT->m_cRowsetsOpen > 0)
15885  return DB_E_OBJECTOPEN; // Don't
15886  // allow
15887  // property
15888  // sets
15889  // on
15890  // an
15891  // open
15892  // rowset
15893 
15894 HRESULT hr =
15896  (cPropertySets,
15897  rgPropertySets);
15898 
15899 if (SUCCEEDED
15900  (hr))
15901  {
15902 
15903  // Scan
15904  // property
15905  // sets to
15906  // allow user
15907  // defined
15908  // properies
15909  ULONG ulPropSets = 0;
15910 ULONG ulPropElems = 0;
15911 ULONG ulPropInits = 0;
15912 UPROPSET * pSetA = NULL;
15913 UPROPSET * pSetTemp = NULL;
15914 ULONG l = 0;
15915 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
15916 
15917 CTempBuffer < UPROPSET > tmpBuffer;
15918 pSetA = tmpBuffer.Allocate (cSets);
15919 if (pSetA == NULL)
15920  return E_OUTOFMEMORY; // We
15921  // shouldn't
15922  // get
15923  // this
15924  // but...
15925  pSetTemp =
15926  pT->
15927  _GetPropSet
15928  (&ulPropSets,
15929  &ulPropElems,
15930  pSetA);
15931 
15932 
15933 typedef
15934  const GUID *
15935  PCGUID;
15936 
15937 
15938 for (l = 0;
15939  l <
15940  cSets;
15941  l++)
15942  {
15943 
15944 if (pSetTemp
15945  [l].
15946  bIsChained
15947  !=
15948  true)
15949  ulPropInits++;
15950 
15951 }
15952 
15953 
15954 CTempBuffer
15955  < PCGUID >
15956  tmpBuffer2;
15957 
15958 PCGUID *
15959  ppGuid =
15960  tmpBuffer2.
15961  Allocate
15962  (ulPropInits);
15963 
15964 if (ppGuid ==
15965  NULL)
15966  return
15967  E_OUTOFMEMORY;
15968 
15969 ulPropInits =
15970  0;
15971 
15972 for (l = 0;
15973  l <
15974  cSets;
15975  l++)
15976  {
15977 
15978 if (pSetTemp
15979  [l].
15980  bIsChained
15981  !=
15982  true)
15983  ppGuid
15984  [ulPropInits++]
15985  =
15986  pSetTemp[l].
15987  pPropSet;
15988 }
15989 
15990 
15991 hr =
15992  CUtlProps <
15993  PropClass >::
15995  (0,
15996  cPropertySets,
15997 
15998 rgPropertySets,
15999  ulPropInits,
16000  ppGuid);
16001 }
16002 
16003 return hr;
16004 }
16005 
16006 };
16007 
16008 
16009 
16010 template < class T, class CommandBase = ICommand >
16011 class ATL_NO_VTABLE ICommandImpl: public
16012  CommandBase
16013 
16014  {
16015 
16016 public:
16018  ()
16019 
16020  {
16021 
16022 m_bIsExecuting
16023  = FALSE;
16024 
16025 m_bCancelWhenExecuting
16026  = TRUE;
16027 
16028 m_bCancel =
16029  FALSE;
16030 }
16031 
16032 HRESULT
16033  CancelExecution
16034  ()
16035  {
16036 
16037 T * pT =
16038  (T *) this;
16039 
16040 pT->Lock ();
16041 
16042 m_bCancel =
16043  TRUE;
16044 
16045 pT->
16046  Unlock ();
16047 
16048 return S_OK;
16049 
16050 }
16051 
16052 STDMETHOD
16053  (Cancel) ()
16054  {
16055 
16056 ATLTRACE
16057  (atlTraceDBProvider,
16058  2,
16059  _T
16060  ("ICommandImpl::Cancel\n"));
16061 
16062 HRESULT hr =
16063  S_OK;
16064 
16065 T * pT =
16066  (T *) this;
16067 
16068 
16069 if
16070  (m_bIsExecuting
16071  &&
16072  m_bCancelWhenExecuting)
16073 
16074  {
16075 
16076 hr =
16077  pT->
16078  CancelExecution
16079  ();
16080 
16081 return hr;
16082 }
16083 
16084 if
16085  (m_bIsExecuting
16086  &&
16087  !m_bCancelWhenExecuting)
16088 
16089  hr =
16090  DB_E_CANTCANCEL;
16091 
16092 return hr;
16093 }
16094 
16095 STDMETHOD
16096  (GetDBSession)
16097  (REFIID riid,
16098  IUnknown **
16099  ppSession)
16100  {
16101 
16102 ATLTRACE
16103  (atlTraceDBProvider,
16104  2,
16105  _T
16106  ("ICommandImpl::GetDBSession\n"));
16107 
16108 if (ppSession
16109  ==
16110  NULL)
16111  return
16112  E_INVALIDARG;
16113 
16114 T * pT =
16115  (T *) this;
16116 
16117 ATLASSERT
16118  (pT->
16119  m_spUnkSite
16120  != NULL);
16121 
16122 return pT->
16123  m_spUnkSite->
16124  QueryInterface
16125  (riid,
16126  (void **)
16127  ppSession);
16128 
16129 }
16130 
16131 template
16132  <
16133  class
16134  RowsetClass >
16135 
16136 HRESULT
16137  CreateRowset
16138  (IUnknown *
16139  pUnkOuter,
16140  REFIID riid,
16141 
16142 DBPARAMS *
16143  pParams,
16144  DBROWCOUNT *
16145  pcRowsAffected,
16146 
16147 IUnknown **
16148  ppRowset,
16149 
16150 RowsetClass
16151  *
16152  &pRowsetObj)
16153 
16154  {
16155 
16156 ATLTRACE
16157  (atlTraceDBProvider,
16158  2,
16159  _T
16160  ("ICommandImpl::CreateRowset\n"));
16161 
16162 
16163 HRESULT hr;
16164 
16165 USES_CONVERSION;
16166 
16167  // int
16168  // iBind;
16169  T * pT =
16170  (T *) this;
16171 
16172 
16173 if (pT->
16174  m_strCommandText.
16175  Length
16176  () ==
16177  0)
16178  {
16179 
16180 ATLTRACE
16181  (atlTraceDBProvider,
16182  2,
16183  _T
16184  ("ICommandImpl::No command text specified.\n"));
16185 
16186 return
16187  DB_E_NOCOMMAND;
16188 
16189 }
16190 
16191 if
16192  (InlineIsEqualGUID
16193  (IID_NULL,
16194  riid))
16195  {
16196 
16197 ATLTRACE
16198  (atlTraceDBProvider,
16199  2,
16200  _T
16201  ("IID_NULL was specified in Execute, returning S_OK"));
16202 
16203 return S_OK;
16204 
16205 }
16206 
16207 if (ppRowset
16208  !=
16209  NULL)
16210  *ppRowset =
16211  NULL;
16212  else
16213 
16214 return
16215  E_INVALIDARG;
16216 
16217 if ((pUnkOuter != NULL) && !InlineIsEqualUnknown (riid))
16218  return DB_E_NOAGGREGATION;
16219 CComPolyObject < RowsetClass > *pPolyObj;
16220 if (FAILED (hr = CComPolyObject < RowsetClass >::CreateInstance (pUnkOuter, &pPolyObj)))
16221  return hr;
16222  // Ref the
16223  // created
16224  // COM object
16225  // and Auto
16226  // release it
16227  // on
16228  // failure
16229  CComPtr <
16230  IUnknown >
16231  spUnk;
16232 
16233 hr =
16234  pPolyObj->
16235  QueryInterface
16236  (&spUnk);
16237 
16238 if (FAILED
16239  (hr))
16240  {
16241 
16242 delete pPolyObj; // must
16243  // hand
16244  // delete
16245  // as
16246  // it
16247  // is
16248  // not
16249  // ref'd
16250  return hr;
16251 }
16252 
16253  // Get a
16254  // pointer to
16255  // the Rowset
16256  // instance
16257  pRowsetObj =
16258  &(pPolyObj->
16259  m_contained);
16260 
16261 
16262 if (FAILED
16263  (hr =
16264  pRowsetObj->
16265  FInit
16266  (pT)))
16267 
16268  return hr;
16269 
16270 CComPtr <
16271  IUnknown >
16272  spOuterUnk;
16273 
16274 pT->
16275  QueryInterface
16276  (__uuidof
16277  (IUnknown),
16278  (void **)
16279  &spOuterUnk);
16280 
16281 pRowsetObj->
16282  SetSite
16283  (spOuterUnk);
16284 
16285 pRowsetObj->
16286  m_strCommandText
16287  =
16288  pT->
16289  m_strCommandText;
16290 
16291 if
16292  (pRowsetObj->
16293  m_strCommandText
16294  ==
16295  (BSTR) NULL)
16296 
16297  return
16298  E_OUTOFMEMORY;
16299 
16300 
16301  // Check to
16302  // make sure
16303  // we set any
16304  // 'post'
16305  // properties
16306  // based on
16307  // the riid
16308  // requested.
16309  // Do this
16310  // before
16311  // calling
16312  // Execute in
16313  // case
16314  // provider
16315  // has
16316  // property
16317  // specific
16318  // processing.
16319  if (FAILED
16320  (pRowsetObj->
16321  OnInterfaceRequested
16322  (riid)))
16323 
16324  return hr;
16325 
16326 
16327 // for (iBind = 0; iBind < pT->m_rgBindings.GetCount(); iBind++)
16328  POSITION pos =
16329  pT->
16330  m_rgBindings.
16331  GetStartPosition
16332  ();
16333 
16334 while (pos !=
16335  NULL)
16336 
16337  {
16338 
16339 T::
16340  _BindingVector::
16341  CPair *
16342  pPair =
16343  pT->
16344  m_rgBindings.
16345  GetNext (pos);
16346 
16347 ATLASSERT
16348  (pPair !=
16349  NULL);
16350 
16351 T::
16352  _BindType *
16353  pBind = NULL;
16354 
16355 T::
16356  _BindType *
16357  pBindSrc =
16358  NULL;
16359 
16360 ATLTRY (pBind
16361  =
16362  new
16363  T::
16364  _BindType);
16365 
16366 CAutoPtr <
16367  T::_BindType >
16368  amr (pBind);
16369 
16370 if (pBind ==
16371  NULL)
16372  {
16373 
16374 ATLTRACE
16375  (atlTraceDBProvider,
16376  2,
16377  _T
16378  ("Failed to allocate memory for new Binding\n"));
16379 
16380 return
16381  E_OUTOFMEMORY;
16382 
16383 }
16384 
16385 pBindSrc =
16386  pPair->
16387  m_value;
16388 
16389 if (pBindSrc
16390  ==
16391  NULL)
16392  {
16393 
16394 ATLTRACE
16395  (atlTraceDBProvider,
16396  2,
16397  _T
16398  ("The map appears to be corrupted, failing!!\n"));
16399 
16400 return
16401  E_FAIL;
16402 }
16403 
16404  // if
16405  // (!pRowsetObj->m_rgBindings.SetAt(pPair->m_key,
16406  // pBind))
16407  // {
16408  // ATLTRACE(atlTraceDBProvider,
16409  // 2,
16410  // _T("Failed
16411  // to add
16412  // hAccessor
16413  // to
16414  // Map\n"));
16415  // return
16416  // E_OUTOFMEMORY;
16417  // }
16418  _ATLTRY
16419  {
16420 
16421 pRowsetObj->
16422  m_rgBindings.
16423  SetAt (pPair->
16424  m_key,
16425  pBind);
16426 
16427 }
16428 
16429 _ATLCATCH (e)
16430 
16431  {
16432 
16433 _ATLDELETEEXCEPTION
16434  (e);
16435 
16436 ATLTRACE
16437  (atlTraceDBProvider,
16438  2,
16439  _T
16440  ("Failed to add hAccessor to Map\n"));
16441 
16442 return
16443  E_OUTOFMEMORY;
16444 
16445 }
16446 
16447 if
16448  (pBindSrc->
16449  cBindings)
16450  {
16451 
16452 ATLTRY
16453  (pBind->
16454  pBindings =
16455  new
16456  DBBINDING
16457  [pBindSrc->
16458  cBindings])
16459 
16460  if (pBind->
16461  pBindings
16462  ==
16463  NULL)
16464  {
16465 
16466 ATLTRACE
16467  (atlTraceDBProvider,
16468  2,
16469  _T
16470  ("Failed to Allocate dbbinding Array\n"));
16471 
16472  // We added
16473  // it, must
16474  // now remove
16475  // on
16476  // failure
16477  pRowsetObj->
16478  m_rgBindings.
16479  RemoveKey
16480  (pPair->
16481  m_key);
16482 
16483 return
16484  E_OUTOFMEMORY;
16485 
16486 }
16487 
16488 }
16489 
16490  else
16491 
16492  {
16493 
16494 pBind->pBindings = NULL; // NULL
16495  // Accessor
16496  }
16497 
16498 
16499 pBind->
16500  dwAccessorFlags
16501  =
16502  pBindSrc->
16503  dwAccessorFlags;
16504 
16505 pBind->
16506  cBindings =
16507  pBindSrc->
16508  cBindings;
16509 
16510 pBind->
16511  dwRef = 1;
16512 
16513 memcpy
16514  (pBind->
16515  pBindings,
16516  pBindSrc->
16517  pBindings,
16518  (pBindSrc->
16519  cBindings) *
16520  sizeof
16521  (DBBINDING));
16522 
16523 amr.
16524  Detach ();
16525 }
16526 
16527 
16528  // Execute
16529  // the
16530  // command.
16531  // By
16532  // default,
16533  // we'll
16534  // always
16535  // return a
16536  // rowset.
16537  // If you do
16538  // not wish
16539  // to
16540  // return a
16541  // rowset,
16542  // set this
16543  // value to
16544  // false in
16545  // your
16546  // Execute
16547  // function.
16548  // If you
16549  // return
16550  // false, we
16551  // will not
16552  // return a
16553  // rowset
16554  // pointer,
16555  // regardless
16556  // of whether
16557  // the user
16558  // requests
16559  // one.
16560  m_bRowsetReturned
16561  = true;
16562 
16563 
16564 HRESULT
16565  hrExecute;
16566 
16567 if (FAILED
16568  (hrExecute
16569  =
16570  pRowsetObj->
16571  Execute
16572  (pParams,
16573  pcRowsAffected)))
16574 
16575  return
16576  hrExecute;
16577 /*
16578  CComVariant varMaxRows;
16579  if (SUCCEEDED(pRowsetObj->GetPropValue(&DBPROPSET_ROWSET, DBPROP_MAXROWS, &varMaxRows)))
16580  {
16581  if( varMaxRows.lVal > 0 )
16582  {
16583  if( pRowsetObj->m_rgRowData.GetCount() > (size_t)varMaxRows.lVal )
16584  {
16585  pRowsetObj->m_rgRowData.RemoveAt( varMaxRows.lVal,
16586  pRowsetObj->m_rgRowData.GetCount() - varMaxRows.lVal );
16587  }
16588  }
16589  }
16590 */
16591  if
16592  (InlineIsEqualGUID
16593  (riid,
16594  IID_NULL)
16595  || ppRowset
16596  == NULL)
16597  {
16598 
16599 if (ppRowset
16600  !=
16601  NULL)
16602  *ppRowset =
16603  NULL;
16604 
16605 return
16606  hrExecute;
16607 }
16608 
16609 
16610 if
16611  (m_bRowsetReturned
16612  !=
16613  false)
16614  hr =
16615  pPolyObj->
16616  QueryInterface
16617  (riid,
16618  (void **)
16619  ppRowset);
16620  else
16621 
16622 return hr;
16623 
16624 
16625 if (FAILED
16626  (hr))
16627  return hr;
16628 
16629 
16630 return
16631  hrExecute;
16632 }
16633 
16634 
16635 unsigned m_bIsExecuting: 1;
16636 unsigned m_bCancelWhenExecuting: 1;
16637 unsigned m_bCancel: 1;
16638 unsigned m_bRowsetReturned: 1;
16639 };
16640 
16641 
16642 template < class T >
16643 class ATL_NO_VTABLE ICommandTextImpl:public
16644  ICommandImpl <
16645  T,
16646  ICommandText >
16647 
16648  {
16649 
16650 public:
16651 
16653  {
16654 
16655 m_guidDialect
16656  =
16657  DBGUID_DEFAULT;
16658 
16659 m_cRowsetsOpen
16660  = 0;
16661 }
16662 
16663 
16664 STDMETHOD
16665  (GetCommandText)
16666  (GUID *
16667  pguidDialect,
16668  LPOLESTR *
16669  ppwszCommand)
16670 
16671  {
16672 
16673 ATLTRACE
16674  (atlTraceDBProvider,
16675  2,
16676  _T
16677  ("ICommandTextImpl::GetCommandText\n"));
16678 
16679 
16680 T * pT =
16681  (T *) this;
16682 
16683 T::
16684  ObjectLock
16685  cab (pT);
16686 
16687 
16688 GUID
16689  guidOrig =
16690  IID_NULL;
16691 
16692 
16693 if
16694  (pguidDialect
16695  != NULL)
16696  {
16697 
16698 guidOrig =
16699  *pguidDialect;
16700 
16701 *pguidDialect
16702  = GUID_NULL;
16703 
16704 }
16705 
16706 if
16707  (ppwszCommand
16708  == NULL)
16709  {
16710 
16711 ATLTRACE
16712  (atlTraceDBProvider,
16713  0,
16714  _T
16715  ("ICommandTextImpl::GetCommandText Bad Command buffer\n"));
16716 
16717 return
16718  E_INVALIDARG;
16719 
16720 }
16721 
16722 if
16723  (m_strCommandText.
16724  m_str == NULL
16725  ||
16726  *
16727  (m_strCommandText.
16728  m_str) ==
16729  NULL)
16730  {
16731 
16732 ATLTRACE
16733  (atlTraceDBProvider,
16734  0,
16735  _T
16736  ("ICommandTextImpl::GetCommandText Bad Command buffer\n"));
16737 
16738 return
16739  DB_E_NOCOMMAND;
16740 
16741 }
16742 
16743 
16744 *ppwszCommand
16745  =
16746  AtlAllocTaskWideString
16747  (m_strCommandText.
16748  m_str);
16749 
16750 if
16751  (ppwszCommand
16752  != NULL)
16753  {
16754 
16755 HRESULT
16756  hrDialect =
16757  S_OK;
16758 
16759 if
16760  (pguidDialect
16761  != NULL)
16762  {
16763 
16764 if
16765  (!InlineIsEqualGUID
16766  (guidOrig,
16767  m_guidDialect))
16768 
16769  hrDialect =
16770  DB_S_DIALECTIGNORED;
16771 
16772 *pguidDialect
16773  =
16774  m_guidDialect;
16775 
16776 }
16777 
16778 return
16779  hrDialect;
16780 }
16781 
16782  else
16783 
16784 return
16785  E_OUTOFMEMORY;
16786 
16787 }
16788 
16789 
16790 STDMETHOD
16791  (SetCommandText)
16792  (REFGUID
16793  rguidDialect,
16794  LPCOLESTR
16795  pwszCommand)
16796 
16797  {
16798 
16799 T * pT =
16800  (T *) this;
16801 
16802 T::
16803  ObjectLock
16804  cab (pT);
16805 
16806 
16807 ATLTRACE
16808  (atlTraceDBProvider,
16809  2,
16810  _T
16811  ("ICommandTextImpl::SetCommandText\n"));
16812 
16813 
16814 if
16815  (m_cRowsetsOpen
16816  >
16817  0)
16818  return
16819  DB_E_OBJECTOPEN;
16820 
16821 
16822 if
16823  (InlineIsEqualGUID
16824  (rguidDialect,
16825  DBGUID_SQL))
16826 
16827  {
16828 
16829 CComVariant
16830  varByRef;
16831 
16832 HRESULT hr =
16833  pT->
16834  GetPropValue
16835  (&DBPROPSET_ROWSET,
16836  DBPROPVAL_SQL_NONE,
16837  &varByRef);
16838 
16839 if (FAILED
16840  (hr)
16841  ||
16842  varByRef.
16843  boolVal
16844  !=
16846 
16847  return
16848  DB_E_DIALECTNOTSUPPORTED;
16849 
16850 }
16851 
16852 if
16853  (InlineIsEqualGUID
16854  (rguidDialect,
16855  GUID_NULL))
16856 
16857  return
16858  DB_E_DIALECTNOTSUPPORTED;
16859 
16860 m_guidDialect
16861  =
16862  rguidDialect;
16863 
16864 m_strCommandText
16865  = pwszCommand;
16866 
16867 return S_OK;
16868 
16869 }
16870 
16871 
16872 LONG
16873  m_cRowsetsOpen;
16874 
16875 CComBSTR
16876  m_strCommandText;
16877 
16878 GUID
16879  m_guidDialect;
16880 
16881 };
16882 
16883 
16884 // ISessionPropertiesImpl
16885 template < class T, class PropClass = T >
16886 class ATL_NO_VTABLE ISessionPropertiesImpl:
16887 public
16888  ISessionProperties,
16889 
16890 public
16891  CUtlProps <
16892  PropClass >
16893  {
16894 
16895 public:
16896 typedef
16897  PropClass
16899 
16900 
16901 STDMETHOD
16902  (GetProperties)
16903  (ULONG
16904  cPropertyIDSets,
16905 
16906 const
16907  DBPROPIDSET
16908  rgPropertyIDSets
16909  [],
16910 
16911 ULONG *
16912  pcPropertySets,
16913 
16914 DBPROPSET **
16915  prgPropertySets)
16916 
16917  {
16918 
16919 ATLTRACE
16920  (atlTraceDBProvider,
16921  2,
16922  _T
16923  ("ISessionPropertiesImpl::GetProperties\n"));
16924 
16925 T * pT;
16926 
16927 pT =
16928  static_cast <
16929  T * >(this);
16930 
16931 
16932  // You can't
16933  // retrieve
16934  // PROPERTIESINERROR
16935  // here (it
16936  // would be
16937  // processed
16938  // like any
16939  // other
16940  // property
16941  // set.
16942  // Therefore,
16943  // turn
16944  // checking
16945  // off
16946  m_dwFlags |=
16948 
16949 HRESULT hr =
16951  (cPropertyIDSets,
16952  rgPropertyIDSets,
16953 
16954 pcPropertySets,
16955  prgPropertySets);
16956 
16957 
16958 if
16959  (SUCCEEDED
16960  (hr))
16961  {
16962 
16963  // Scan
16964  // property
16965  // sets to
16966  // allow user
16967  // defined
16968  // properies
16969  ULONG ulPropSets = 0;
16970 ULONG ulPropElems = 0;
16971 ULONG ulPropInits = 0;
16972 UPROPSET * pSetA = NULL;
16973 UPROPSET * pSetTemp = NULL;
16974 ULONG l = 0;
16975 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
16976 
16977 CTempBuffer < UPROPSET > tmpBuffer;
16978 pSetA = tmpBuffer.Allocate (cSets);
16979 if (pSetA == NULL)
16980  return E_OUTOFMEMORY; // We
16981  // shouldn't
16982  // get
16983  // this
16984  // but...
16985  pSetTemp =
16986  pT->
16987  _GetPropSet
16988  (&ulPropSets,
16989  &ulPropElems,
16990  pSetA);
16991 
16992 
16993 typedef
16994  const GUID *
16995  PCGUID;
16996 
16997 
16998 for (l = 0;
16999  l <
17000  cSets;
17001  l++)
17002  {
17003 
17004 if (pSetTemp
17005  [l].
17006  bIsChained
17007  !=
17008  true)
17009  ulPropInits++;
17010 
17011 }
17012 
17013 
17014 CTempBuffer
17015  < PCGUID >
17016  tmpBuffer2;
17017 
17018 PCGUID *
17019  ppGuid =
17020  tmpBuffer2.
17021  Allocate
17022  (ulPropInits);
17023 
17024 if (ppGuid ==
17025  NULL)
17026  return
17027  E_OUTOFMEMORY;
17028 
17029 ulPropInits =
17030  0;
17031 
17032 for (l = 0;
17033  l <
17034  cSets;
17035  l++)
17036  {
17037 
17038 if (pSetTemp
17039  [l].
17040  bIsChained
17041  !=
17042  true)
17043  ppGuid
17044  [ulPropInits++]
17045  =
17046  pSetTemp[l].
17047  pPropSet;
17048 }
17049 
17050 
17051 hr =
17052  CUtlProps <
17053  PropClass >::
17055  (cPropertyIDSets,
17056 
17057 rgPropertyIDSets,
17058  pcPropertySets,
17059  prgPropertySets,
17060 
17061 ulPropInits,
17062  ppGuid);
17063 }
17064 
17065 return hr;
17066 
17067 }
17068 
17069 
17070 STDMETHOD
17071  (SetProperties)
17072  (ULONG
17073  cPropertySets,
17074 
17075 DBPROPSET
17076  rgPropertySets
17077  [])
17078  {
17079 
17080 ATLTRACE
17081  (atlTraceDBProvider,
17082  2,
17083  _T
17084  ("ISessionPropertiesImpl::SetProperties"));
17085 
17086 T * pT;
17087 
17088 pT =
17089  static_cast <
17090  T * >(this);
17091 
17092 HRESULT hr =
17094  (cPropertySets,
17095  rgPropertySets);
17096 
17097 
17098 if
17099  (SUCCEEDED
17100  (hr))
17101  {
17102 
17103  // Scan
17104  // property
17105  // sets to
17106  // allow user
17107  // defined
17108  // properies
17109  ULONG ulPropSets = 0;
17110 ULONG ulPropElems = 0;
17111 ULONG ulPropInits = 0;
17112 UPROPSET * pSetA = NULL;
17113 UPROPSET * pSetTemp = NULL;
17114 ULONG l = 0;
17115 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
17116 
17117 CTempBuffer < UPROPSET > tmpBuffer;
17118 pSetA = tmpBuffer.Allocate (cSets);
17119 if (pSetA == NULL)
17120  return E_OUTOFMEMORY; // We
17121  // shouldn't
17122  // get
17123  // this
17124  // but...
17125  pSetTemp =
17126  pT->
17127  _GetPropSet
17128  (&ulPropSets,
17129  &ulPropElems,
17130  pSetA);
17131 
17132 
17133 typedef
17134  const GUID *
17135  PCGUID;
17136 
17137 
17138 for (l = 0;
17139  l <
17140  cSets;
17141  l++)
17142  {
17143 
17144 if (pSetTemp
17145  [l].
17146  bIsChained
17147  !=
17148  true)
17149  ulPropInits++;
17150 
17151 }
17152 
17153 
17154 CTempBuffer
17155  < PCGUID >
17156  tmpBuffer2;
17157 
17158 PCGUID *
17159  ppGuid =
17160  tmpBuffer2.
17161  Allocate
17162  (ulPropInits);
17163 
17164 if (ppGuid ==
17165  NULL)
17166  return
17167  E_OUTOFMEMORY;
17168 
17169 ulPropInits =
17170  0;
17171 
17172 for (l = 0;
17173  l <
17174  cSets;
17175  l++)
17176  {
17177 
17178 if (pSetTemp
17179  [l].
17180  bIsChained
17181  !=
17182  true)
17183  ppGuid
17184  [ulPropInits++]
17185  =
17186  pSetTemp[l].
17187  pPropSet;
17188 }
17189 
17190 
17191 hr =
17192  CUtlProps <
17193  PropClass >::
17195  (0,
17196  cPropertySets,
17197  rgPropertySets,
17198 
17199 ulPropInits,
17200  ppGuid);
17201 }
17202 
17203 return hr;
17204 }
17205 
17206 };
17207 
17208 
17209 // Implementation Class
17210 template < class BindType >
17211 class ATL_NO_VTABLE IAccessorImplBase: public
17212  IAccessor
17213 
17214  {
17215 
17216 public:
17217 
17218 STDMETHOD (CreateAccessor) (DBACCESSORFLAGS dwAccessorFlags,
17219 DBCOUNTITEM cBindings,
17220 const DBBINDING rgBindings[],
17221 DBLENGTH /* cbRowSize
17222  */
17223  ,
17224 
17225 HACCESSOR
17226  *
17227  phAccessor,
17228 
17229 DBBINDSTATUS
17230  rgStatus
17231  [])
17232 
17233  {
17234 
17235 if (!
17236  (dwAccessorFlags
17237  &
17238  DBACCESSOR_PARAMETERDATA)
17239  &&
17240  !
17241  (dwAccessorFlags
17242  &
17243  DBACCESSOR_ROWDATA))
17244 
17245  return
17246  DB_E_BADACCESSORFLAGS;
17247 
17248 if
17249  (dwAccessorFlags
17250  ==
17251  DBACCESSOR_INVALID)
17252 
17253  return
17254  DB_E_BADACCESSORFLAGS;
17255 
17256 if
17257  (dwAccessorFlags
17258  >
17259  0x000F)
17260  return
17261  DB_E_BADACCESSORFLAGS;
17262 
17263 BindType *
17264  pBind = NULL;
17265 
17266 ATLTRY (pBind
17267  =
17268  new
17269  BindType)
17270 
17271  if (pBind ==
17272  NULL)
17273  {
17274 
17275 ATLTRACE
17276  (atlTraceDBProvider,
17277  0,
17278  _T
17279  ("Failed to allocate ATL Binding struct\n"));
17280 
17281 return
17282  E_OUTOFMEMORY;
17283 
17284 }
17285 
17286 if
17287  (cBindings)
17288  {
17289 
17290 ATLTRY
17291  (pBind->
17292  pBindings =
17293  new
17294  DBBINDING
17295  [cBindings])
17296 
17297  if (pBind->
17298  pBindings
17299  ==
17300  NULL)
17301  {
17302 
17303 delete pBind;
17304 
17305 return
17306  E_OUTOFMEMORY;
17307 
17308 }
17309 
17310 }
17311 
17312  else
17313 
17314 pBind->pBindings = NULL; // NULL
17315  // Accessor
17316 
17317 pBind->
17318  dwAccessorFlags
17319  =
17320  dwAccessorFlags;
17321 
17322 pBind->
17323  cBindings =
17324  cBindings;
17325 
17326 pBind->
17327  dwRef = 1;
17328 
17329 memcpy
17330  (pBind->
17331  pBindings,
17332  rgBindings,
17333  cBindings *
17334  sizeof
17335  (DBBINDING));
17336 
17337 DBBINDSTATUS
17338  status =
17339  DBBINDSTATUS_OK;
17340 
17341 memset
17342  (rgStatus,
17343  status,
17344  sizeof
17345  (DBBINDSTATUS)
17346  * cBindings);
17347 
17348 *phAccessor =
17349  (ULONG_PTR)
17350  pBind;
17351 
17352 return S_OK;
17353 
17354 }
17355 
17356 BOOL
17357  HasFlag
17358  (DBTYPE
17359  dbToCheck,
17360  DBTYPE
17361  dbCombo)
17362  {
17363 
17364 return ((dbToCheck & dbCombo) == dbCombo);
17365 }
17366 
17367 HRESULT
17368  ValidateBindings
17369  (DBCOUNTITEM
17370  cBindings,
17371  const
17372  DBBINDING
17373  rgBindings[],
17374 
17375 DBBINDSTATUS
17376  rgStatus[],
17377  bool
17378  bHasBookmarks)
17379 
17380  {
17381 
17382 HRESULT hr =
17383  S_OK;
17384 
17385 
17386 for (ULONG
17387  iBinding
17388  = 0;
17389  iBinding
17390  <
17391  cBindings;
17392  iBinding++)
17393 
17394  {
17395 
17396 const
17397  DBBINDING &
17398  rBindCur =
17399  rgBindings
17400  [iBinding];
17401 
17402 if (rBindCur.
17403  iOrdinal
17404  == 0)
17405  {
17406 
17407 if
17408  (!m_bIsCommand
17409  &&
17410  !bHasBookmarks)
17411 
17412  {
17413 
17414 hr =
17415  DB_E_ERRORSOCCURRED;
17416 
17417 rgStatus
17418  [iBinding] =
17419  DBBINDSTATUS_BADORDINAL;
17420 
17421 continue;
17422 }
17423 
17424 }
17425 
17426 if (rBindCur.dwPart == 0) // nothing
17427  // to
17428  // bind
17429  // to
17430  {
17431 
17432 hr =
17433  DB_E_ERRORSOCCURRED;
17434 
17435 rgStatus
17436  [iBinding] =
17437  DBBINDSTATUS_BADBINDINFO;
17438 
17439 continue;
17440 }
17441 
17442 if (HasFlag
17443  (rBindCur.
17444  wType,
17445  (DBTYPE_BYREF
17446  |
17447  DBTYPE_ARRAY)))
17448 
17449  {
17450 
17451 hr =
17452  DB_E_ERRORSOCCURRED;
17453 
17454 rgStatus
17455  [iBinding] =
17456  DBBINDSTATUS_BADBINDINFO;
17457 
17458 continue;
17459 }
17460 
17461 if (HasFlag
17462  (rBindCur.
17463  wType,
17464  (DBTYPE_BYREF
17465  |
17466  DBTYPE_VECTOR)))
17467 
17468  {
17469 
17470 hr =
17471  DB_E_ERRORSOCCURRED;
17472 
17473 rgStatus
17474  [iBinding] =
17475  DBBINDSTATUS_BADBINDINFO;
17476 
17477 continue;
17478 }
17479 
17480 if (HasFlag
17481  (rBindCur.
17482  wType,
17483  (DBTYPE_VECTOR
17484  |
17485  DBTYPE_ARRAY)))
17486 
17487  {
17488 
17489 hr =
17490  DB_E_ERRORSOCCURRED;
17491 
17492 rgStatus
17493  [iBinding] =
17494  DBBINDSTATUS_BADBINDINFO;
17495 
17496 continue;
17497 }
17498 
17499 if (rBindCur.
17500  wType ==
17501  DBTYPE_NULL
17502  ||
17503  rBindCur.
17504  wType ==
17505  DBTYPE_EMPTY)
17506 
17507  {
17508 
17509 hr =
17510  DB_E_ERRORSOCCURRED;
17511 
17512 rgStatus
17513  [iBinding] =
17514  DBBINDSTATUS_BADBINDINFO;
17515 
17516 continue;
17517 }
17518 
17519 if (HasFlag
17520  (rBindCur.
17521  wType,
17522  DBTYPE_RESERVED))
17523 
17524  {
17525 
17526 hr =
17527  DB_E_ERRORSOCCURRED;
17528 
17529 rgStatus
17530  [iBinding] =
17531  DBBINDSTATUS_BADBINDINFO;
17532 
17533 continue;
17534 }
17535 
17536  // DBTYPE_BYREF
17537  // must be
17538  // accompanied
17539  // by other
17540  // valid
17541  // type
17542  if (rBindCur.
17543  wType ==
17544  (DBTYPE_BYREF
17545  |
17546  DBTYPE_EMPTY)
17547 
17548  ||rBindCur.
17549  wType ==
17550  (DBTYPE_BYREF
17551  |
17552  DBTYPE_NULL)
17553 
17554  ||rBindCur.
17555  wType ==
17556  DBTYPE_BYREF)
17557 
17558  {
17559 
17560 hr =
17561  DB_E_ERRORSOCCURRED;
17562 
17563 rgStatus
17564  [iBinding] =
17565  DBBINDSTATUS_BADBINDINFO;
17566 
17567 continue;
17568 }
17569 
17570 
17571  // If someone
17572  // attempts
17573  // to set
17574  // DBBINDFLAG_HTML
17575  // on a
17576  // non-string
17577  // column,
17578  // generate a
17579  // BADBINDINFO
17580  // error.
17581  if (rBindCur.
17582  wType !=
17583  DBTYPE_STR
17584  &&
17585  rBindCur.
17586  wType !=
17587  DBTYPE_WSTR
17588  &&
17589 
17590 rBindCur.
17591  dwFlags &
17592  DBBINDFLAG_HTML)
17593 
17594  {
17595 
17596 hr =
17597  DB_E_ERRORSOCCURRED;
17598 
17599 rgStatus
17600  [iBinding] =
17601  DBBINDSTATUS_BADBINDINFO;
17602 
17603 continue;
17604 }
17605 
17606 
17607  // the
17608  // dwFlags
17609  // parameter
17610  // must be 0
17611  // or
17612  // DBBINDFLAG_HTML,
17613  //
17614  // all other
17615  // values
17616  // will
17617  // return an
17618  // error.
17619  if (rBindCur.
17620  dwFlags !=
17621  0
17622  &&
17623  rBindCur.
17624  dwFlags !=
17625  DBBINDFLAG_HTML)
17626 
17627  {
17628 
17629 hr =
17630  DB_E_ERRORSOCCURRED;
17631 
17632 rgStatus
17633  [iBinding] =
17634  DBBINDSTATUS_BADBINDINFO;
17635 
17636 continue;
17637 }
17638 
17639 
17640 if
17641  (rBindCur.
17642  dwMemOwner ==
17643  DBMEMOWNER_PROVIDEROWNED)
17644 
17645  {
17646 
17647 BOOL
17648  bIsPointerType
17649  =
17650  HasFlag
17651  (rBindCur.
17652  wType,
17653  DBTYPE_BYREF)
17654  ||
17655 
17656 HasFlag
17657  (rBindCur.
17658  wType,
17659  DBTYPE_VECTOR)
17660  ||
17661 
17662 HasFlag
17663  (rBindCur.
17664  wType,
17665  DBTYPE_ARRAY)
17666  ||
17667 
17668 HasFlag ((DBTYPE) (~(DBTYPE_BYREF) & rBindCur.wType), DBTYPE_BSTR);
17669 if (!bIsPointerType)
17670  {
17671 
17672 hr =
17673  DB_E_ERRORSOCCURRED;
17674 
17675 rgStatus
17676  [iBinding] =
17677  DBBINDSTATUS_BADBINDINFO;
17678 
17679 continue;
17680 }
17681 
17682 }
17683 
17684  else
17685  if (rBindCur.
17686  dwMemOwner
17687  !=
17688  DBMEMOWNER_CLIENTOWNED)
17689 
17690  {
17691 
17692  // the
17693  // dwMemOwner
17694  // flag is
17695  // supposed
17696  // to be
17697  // ignored
17698  // for
17699  // reference
17700  // accessors
17701  // (see the
17702  // description
17703  // of
17704  // DBBINDING
17705  // structure
17706  // in MSDN),
17707  // otherwise
17708  // dwMemOwner
17709  // should
17710  // have a
17711  // value of
17712  // DBMEMOWNER_CLIENTOWNED
17713  // or
17714  // DBMEMOWNER_PROVIDEROWNED
17715  if (!HasFlag
17716  (rBindCur.
17717  wType,
17718  DBTYPE_BYREF))
17719 
17720  {
17721 
17722 hr =
17723  DB_E_ERRORSOCCURRED;
17724 
17725 rgStatus
17726  [iBinding] =
17727  DBBINDSTATUS_BADBINDINFO;
17728 
17729 continue;
17730 }
17731 
17732 }
17733 
17734 }
17735 
17736 return hr;
17737 }
17738 
17739 
17740 unsigned m_bIsCommand: 1;
17741 unsigned m_bHasParamaters: 1;
17742 unsigned m_bIsChangeable: 1;
17743 };
17744 
17745 
17746 // IAccessorImpl
17747 template < class T, class BindType = ATLBINDINGS,
17748 class BindingVector = CAtlMap < HACCESSOR, BindType * >>
17749 class ATL_NO_VTABLE IAccessorImpl:public
17751  < BindType >
17752  {
17753 
17754 public:
17755 typedef
17756  BindType
17758 
17759 typedef
17760  BindingVector
17762 
17764  ()
17765  {
17766 
17767 m_bIsCommand = FALSE;
17768 m_bHasParamaters = FALSE;
17769 m_bIsChangeable = FALSE;
17770 }
17771 OUT_OF_LINE HRESULT InternalFinalConstruct (IUnknown * /* pUnkThis
17772  */
17773  )
17774  {
17775 
17776 CComPtr < ICommand > spCommand;
17777 CComPtr < ICommandWithParameters > spCommandWithParameters;
17778 T * pT = (T *) this;
17779 
17780 pT->_InternalQueryInterface (IID_ICommand, (void **) &spCommand);
17781 
17782 if (spCommand != NULL) // It's
17783  // a
17784  // command
17785  {
17786 
17787 m_bIsCommand
17788  = TRUE;
17789 
17790 pT->
17791  _InternalQueryInterface
17792  (IID_ICommandWithParameters,
17793  (void **)
17794  &spCommandWithParameters);
17795 
17796 m_bHasParamaters
17797  =
17798  spCommandWithParameters
17799  != NULL;
17800 
17801 
17802 }
17803 return
17804  S_OK;
17805 }
17806 
17807 HRESULT
17808  FinalConstruct
17809  ()
17810  {
17811 
17812 T * pT =
17813  (T *) this;
17814 
17815 return
17816  InternalFinalConstruct
17817  (pT->
17818  GetUnknown
17819  ());
17820 }
17821 
17822 void
17823  FinalRelease
17824  ()
17825  {
17826 
17827 #ifdef _DEBUG
17828  if
17829  (m_rgBindings.
17830  GetCount ())
17831 
17832  ATLTRACE
17833  (atlTraceDBProvider,
17834  0,
17835  _T
17836  ("IAccessorImpl::~IAccessorImpl Bindings still in vector, removing\n"));
17837 
17838 #endif // _DEBUG
17839  while
17840  (m_rgBindings.
17841  GetCount ())
17842 
17843  ReleaseAccessor
17844  ((HACCESSOR)
17845  m_rgBindings.
17846  GetKeyAt
17847  (m_rgBindings.
17848  GetStartPosition
17849  ()), NULL);
17850 
17851 }
17852 
17853 STDMETHOD
17854  (AddRefAccessor)
17855  (HACCESSOR
17856  hAccessor,
17857 
17858 DBREFCOUNT *
17859  pcRefCount)
17860  {
17861 
17862 ATLTRACE
17863  (atlTraceDBProvider,
17864  2,
17865  _T
17866  ("IAccessorImpl::AddRefAccessor\n"));
17867 
17868 if (hAccessor
17869  ==
17870  NULL)
17871  {
17872 
17873 ATLTRACE
17874  (atlTraceDBProvider,
17875  0,
17876  _T
17877  ("AddRefAccessor : Bad hAccessor\n"));
17878 
17879 return
17880  DB_E_BADACCESSORHANDLE;
17881 
17882 }
17883 
17884 BindType *
17885  pBind;
17886 
17887 if
17888  (!m_rgBindings.
17889  Lookup
17890  (hAccessor,
17891  pBind))
17892  return
17893  DB_E_BADACCESSORHANDLE;
17894 
17895 
17896 ATLASSERT
17897  (pBind);
17898 
17899 ULONG
17900  cRefCount =
17901  T::
17902  _ThreadModel::
17903  Increment ((LONG *) & pBind->dwRef);
17904 
17905 if (pcRefCount != NULL)
17906  *pcRefCount = cRefCount;
17907 
17908 return S_OK;
17909 }
17910 
17912  ATLCOLUMNINFO
17913  *
17914  ValidateHelper
17915  (DBORDINAL *
17916  pcCols,
17917  CComPtr <
17918  IDataConvert
17919  >
17920  &rspConvert)
17921 
17922  {
17923 
17924 T * pT =
17925  (T *) this;
17926 
17927 rspConvert =
17928  pT->
17929  m_spConvert;
17930 
17931 return T::
17932  GetColumnInfo
17933  (pT, pcCols);
17934 
17935 }
17936 
17938  HRESULT
17939  ValidateBindingsFromMetaData
17940  (DBCOUNTITEM
17941  cBindings,
17942  const
17943  DBBINDING
17944  rgBindings[],
17945 
17946 DBBINDSTATUS
17947  rgStatus[],
17948  bool
17949  bHasBookmarks)
17950 
17951  {
17952 
17953 HRESULT hr =
17954  S_OK;
17955 
17956 DBORDINAL
17957  cCols;
17958 
17959 CComPtr <
17960  IDataConvert >
17961  spConvert;
17962 
17963 ATLCOLUMNINFO
17964  * pColInfo =
17965  ValidateHelper
17966  (&cCols,
17967  spConvert);
17968 
17969 ATLASSERT
17970  (pColInfo !=
17971  NULL);
17972 
17973 for
17974  (DBCOUNTITEM
17975  iBinding = 0;
17976  iBinding <
17977  cBindings;
17978  iBinding++)
17979  {
17980 
17981 const DBBINDING & rBindCur = rgBindings[iBinding];
17982 DBORDINAL iOrdAdjusted;
17983 if (bHasBookmarks)
17984  iOrdAdjusted = rBindCur.iOrdinal; // Bookmarks
17985  // start
17986  // with
17987  // ordinal
17988  // 0
17989  else
17990 
17991 iOrdAdjusted = rBindCur.iOrdinal - 1; // Non-bookmarks
17992  // start
17993  // w/
17994  // ordinal
17995  // 1
17996  if (rBindCur.
17997  iOrdinal >
17998  cCols)
17999  {
18000 
18001 hr =
18002  DB_E_ERRORSOCCURRED;
18003 
18004 rgStatus
18005  [iBinding] =
18006  DBBINDSTATUS_BADORDINAL;
18007 
18008 continue;
18009 }
18010 
18011 
18012  // If a
18013  // binding
18014  // specifies
18015  // provider
18016  // owned
18017  // memory,
18018  // and
18019  // specifies
18020  // type
18021  // X | BYREF,
18022  // and the
18023  // provider's
18024  // copy is
18025  // not X or X
18026  // | BYREF,
18027  // return
18028  // DBBINDSTATUS_BADBINDINFO
18029 
18030 if (rBindCur.
18031  dwMemOwner
18032  ==
18033  DBMEMOWNER_PROVIDEROWNED)
18034 
18035  {
18036 
18037 if ((rBindCur.wType & DBTYPE_BYREF) != 0 &&
18038 ((rBindCur.wType & (~DBTYPE_BYREF)) !=
18039 (pColInfo[iOrdAdjusted].wType & (~DBTYPE_BYREF))))
18040  {
18041 
18042 hr =
18043  DB_E_ERRORSOCCURRED;
18044 
18045 rgStatus
18046  [iBinding] =
18047  DBBINDSTATUS_BADBINDINFO;
18048 
18049 continue;
18050 }
18051 
18052 }
18053 
18054 
18055 ATLASSERT
18056  (spConvert !=
18057  NULL);
18058 
18059 HRESULT
18060  hrConvert =
18061  spConvert->
18062  CanConvert
18063  (pColInfo
18064  [iOrdAdjusted].
18065  wType,
18066  rBindCur.
18067  wType);
18068 
18069 if (FAILED
18070  (hrConvert)
18071  ||
18072  hrConvert
18073  ==
18074  S_FALSE)
18075 
18076  {
18077 
18078 hr =
18079  DB_E_ERRORSOCCURRED;
18080 
18081 rgStatus
18082  [iBinding] =
18083  DBBINDSTATUS_UNSUPPORTEDCONVERSION;
18084 
18085 continue;
18086 }
18087 
18088 }
18089 
18090 return hr;
18091 }
18092 
18093 STDMETHOD
18094  (CreateAccessor)
18095  (DBACCESSORFLAGS
18096  dwAccessorFlags,
18097 
18098 DBCOUNTITEM
18099  cBindings,
18100 
18101 const
18102  DBBINDING
18103  rgBindings[],
18104 
18105 DBLENGTH
18106  cbRowSize,
18107 
18108 HACCESSOR *
18109  phAccessor,
18110 
18111 DBBINDSTATUS
18112  rgStatus[])
18113  {
18114 
18115 ATLTRACE
18116  (atlTraceDBProvider,
18117  2,
18118  _T
18119  ("IAccessorImpl::CreateAccessor\n"));
18120 
18121 T * pT =
18122  (T *) this;
18123 
18124 T::
18125  ObjectLock
18126  cab (pT);
18127 
18128 
18129 if
18130  (!phAccessor)
18131 
18132  {
18133 
18134 ATLTRACE
18135  (atlTraceDBProvider,
18136  0,
18137  _T
18138  ("IAccessorImpl::CreateAccessor : Inavlid NULL Parameter for HACCESSOR*\n"));
18139 
18140 return
18141  E_INVALIDARG;
18142 
18143 }
18144 
18145 *phAccessor =
18146  NULL;
18147 
18148 if (cBindings
18149  != 0
18150  &&
18151  rgBindings
18152  ==
18153  NULL)
18154  {
18155 
18156 ATLTRACE
18157  (atlTraceDBProvider,
18158  0,
18159  _T
18160  ("IAccessorImpl::CreateAccessor : Bad Binding array\n"));
18161 
18162 return
18163  E_INVALIDARG;
18164 
18165 }
18166 
18167 if
18168  (dwAccessorFlags
18169  &
18170  DBACCESSOR_PASSBYREF)
18171 
18172  {
18173 
18174 CComVariant
18175  varByRef;
18176 
18177 HRESULT hr =
18178  pT->
18179  GetPropValue
18180  (&DBPROPSET_ROWSET,
18181 
18182 DBPROP_BYREFACCESSORS,
18183  &varByRef);
18184 
18185 if (FAILED
18186  (hr)
18187  ||
18188  varByRef.
18189  boolVal
18190  ==
18192 
18193  return
18194  DB_E_BYREFACCESSORNOTSUPPORTED;
18195 
18196 }
18197 
18198 if
18199  (!m_bHasParamaters)
18200 
18201  {
18202 
18203 if
18204  (dwAccessorFlags
18205  &
18206  DBACCESSOR_PARAMETERDATA)
18207 
18208  return
18209  DB_E_BADACCESSORFLAGS;
18210 
18211 }
18212 
18213 
18214  // since our
18215  // accessor
18216  // does not
18217  // provide
18218  // any
18219  // further
18220  // restrictions
18221  // or
18222  // optimizations
18223  // based
18224  // on the
18225  // DBACCESSOR_OPTIMIZED
18226  // flag, the
18227  // flag will
18228  // be
18229  // ignored.
18230  // In
18231  // particular
18232  // we will
18233  // not be
18234  // returning
18235  // this flag
18236  // in the
18237  // call to
18238  // IAccessor::GetBindings.
18239  // This way
18240  // we will
18241  // be
18242  // complient
18243  // with the
18244  // OLEDB
18245  // specifications
18246  // and we
18247  // will not
18248  // have to
18249  // prevent
18250  // the
18251  // client
18252  // from
18253  // creating
18254  // additional
18255  // accessors
18256  // after the
18257  // first row
18258  // is
18259  // fetched.
18260  DBACCESSORFLAGS
18261  dwMask =
18262  DBACCESSOR_OPTIMIZED;
18263 
18264 dwAccessorFlags
18265  &= ~dwMask;
18266 
18267 
18268 CComVariant
18269  varUpdate;
18270 
18271 HRESULT hr =
18272  pT->
18273  GetPropValue
18274  (&DBPROPSET_ROWSET,
18275  DBPROP_UPDATABILITY,
18276  &varUpdate);
18277 
18278 m_bIsChangeable
18279  =
18280  (SUCCEEDED
18281  (hr)
18282  &&
18283  (varUpdate.
18284  iVal &
18285  DBPROPVAL_UP_INSERT));
18286 
18287 
18288 if
18289  (m_bIsCommand
18290  ||
18291  !m_bIsChangeable)
18292 
18293  {
18294 
18295 if (cBindings == 0) // No
18296  // NULL
18297  // Accessors
18298  // on
18299  // the
18300  // command
18301  return
18302  DB_E_NULLACCESSORNOTSUPPORTED;
18303 
18304 }
18305 
18306 
18307 CTempBuffer < DBBINDSTATUS > tmpBuffer;
18308 if (rgStatus == NULL && cBindings) // Create
18309  // a
18310  // fake
18311  // status
18312  // array
18313  //
18314  rgStatus =
18315  tmpBuffer.
18316  Allocate
18317  (cBindings);
18318 
18319 
18320  // Validate
18321  // the
18322  // Binding
18323  // passed
18324  bool
18325  bHasBookmarks
18326  = false;
18327 
18328 CComVariant
18329  varBookmarks;
18330 
18331 HRESULT
18332  hrLocal =
18333  pT->
18334  GetPropValue
18335  (&DBPROPSET_ROWSET,
18336  DBPROP_BOOKMARKS,
18337  &varBookmarks);
18338 
18339 bHasBookmarks
18340  =
18341  (hrLocal ==
18342  S_OK
18343  &&
18344  varBookmarks.
18345  boolVal !=
18347 
18348 
18349 hr =
18351  (cBindings,
18352  rgBindings,
18353  rgStatus,
18354  bHasBookmarks);
18355 
18356 if (FAILED
18357  (hr))
18358  return hr;
18359 
18360 if
18361  (!m_bIsCommand)
18362 
18363  {
18364 
18365 hr =
18366  ValidateBindingsFromMetaData
18367  (cBindings,
18368  rgBindings,
18369  rgStatus,
18370 
18371 bHasBookmarks);
18372 
18373 if (FAILED
18374  (hr))
18375  return hr;
18376 }
18377 
18378 hr =
18380  <
18381  BindType >::
18383  (dwAccessorFlags,
18384  cBindings,
18385 
18386 rgBindings,
18387  cbRowSize,
18388  phAccessor,
18389  rgStatus);
18390 
18391 if (SUCCEEDED
18392  (hr))
18393  {
18394 
18395 ATLASSERT
18396  (*phAccessor
18397  != NULL);
18398 
18399 BindType *
18400  pBind =
18401  (BindType *) *
18402  phAccessor;
18403  // hr =
18404  // m_rgBindings.SetAt((HACCESSOR)pBind,
18405  // pBind) ?
18406  // S_OK :
18407  // E_OUTOFMEMORY;
18408  _ATLTRY
18409  {
18410 
18411 m_rgBindings.
18412  SetAt ((HACCESSOR) pBind, pBind);
18413 hr = S_OK;
18414 }
18415 
18416 _ATLCATCH (e)
18417 
18418  {
18419 
18420 _ATLDELETEEXCEPTION
18421  (e);
18422 
18423 hr =
18424  E_OUTOFMEMORY;
18425 
18426 }
18427 
18428 }
18429 
18430 return hr;
18431 
18432 }
18433 
18434 
18435 STDMETHOD
18436  (GetBindings)
18437  (HACCESSOR
18438  hAccessor,
18439 
18440 DBACCESSORFLAGS
18441  *
18442  pdwAccessorFlags,
18443 
18444 DBCOUNTITEM
18445  * pcBindings,
18446 
18447 DBBINDING **
18448  prgBindings)
18449 
18450  {
18451 
18452 ATLTRACE
18453  (atlTraceDBProvider,
18454  2,
18455  _T
18456  ("IAccessorImpl::GetBindings\n"));
18457 
18458 
18459  // Zero
18460  // output
18461  // parameters
18462  // in case of
18463  // failure
18464  if
18465  (pdwAccessorFlags
18466  !=
18467  NULL)
18468  *pdwAccessorFlags
18469  = NULL;
18470 
18471 
18472 if
18473  (pcBindings !=
18474  NULL)
18475  *pcBindings =
18476  NULL;
18477 
18478 
18479 if
18480  (prgBindings
18481  !=
18482  NULL)
18483  *prgBindings =
18484  NULL;
18485 
18486  // Check if
18487  // any of the
18488  // out params
18489  // are NULL
18490  // pointers
18491  if ((pdwAccessorFlags && pcBindings && prgBindings) == NULL)
18492  return E_INVALIDARG;
18493 
18494 BindType * pBind;
18495 bool bFound = m_rgBindings.Lookup ((INT_PTR) hAccessor, pBind);
18496 HRESULT hr = DB_E_BADACCESSORHANDLE;
18497 if (bFound && pBind != NULL)
18498  {
18499 
18500 *pdwAccessorFlags
18501  =
18502  pBind->
18503  dwAccessorFlags;
18504 
18505 *pcBindings =
18506  pBind->
18507  cBindings;
18508  // Get NULL
18509  // for NULL
18510  // Accessor
18511  *prgBindings = (pBind->cBindings) ? (DBBINDING *) CoTaskMemAlloc (*pcBindings * sizeof (DBBINDING)) : NULL;
18512 if (*prgBindings == NULL && pBind->cBindings) // No
18513  // Error
18514  // if
18515  // NULL
18516  // Accessor
18517  return
18518  E_OUTOFMEMORY;
18519 
18520 memcpy
18521  (*prgBindings,
18522  pBind->
18523  pBindings,
18524  sizeof
18525  (DBBINDING) *
18526  (*pcBindings));
18527 
18528 hr = S_OK;
18529 }
18530 
18531 return hr;
18532 }
18533 
18534 
18535 STDMETHOD
18536  (ReleaseAccessor)
18537  (HACCESSOR
18538  hAccessor,
18539 
18540 DBREFCOUNT *
18541  pcRefCount)
18542  {
18543 
18544 ATLTRACE
18545  (atlTraceDBProvider,
18546  2,
18547  _T
18548  ("IAccessorImpl::ReleaseAccessor\n"));
18549 
18550 T::
18551  ObjectLock
18552  cab ((T *)
18553  this);
18554 
18555 BindType *
18556  pBind;
18557 
18558 bool bFound =
18559  m_rgBindings.
18560  Lookup ((INT_PTR) hAccessor, pBind);
18561 if (!bFound || pBind == NULL)
18562  return DB_E_BADACCESSORHANDLE;
18563 DBREFCOUNT cRefCount = T::_ThreadModel::Decrement ((LONG *) & pBind->dwRef);
18564 if (pcRefCount != NULL)
18565  *pcRefCount = cRefCount;
18566 if (cRefCount == 0)
18567  {
18568 
18569 delete
18570  []pBind->
18571  pBindings;
18572 
18573 delete pBind;
18574 
18575 return
18576  m_rgBindings.
18577  RemoveKey
18578  (hAccessor) ?
18579  S_OK :
18580  DB_E_BADACCESSORHANDLE;
18581 
18582 }
18583 
18584 return S_OK;
18585 }
18586 
18587 
18588 BindingVector
18589  m_rgBindings;
18590 
18591 };
18592 
18593 
18594 #define BEGIN_PROVIDER_COLUMN_MAP(theClass) \
18595  typedef
18596  theClass
18598  \
18599 template <
18600  class T >
18601  \
18602 static ATL::
18603  ATLCOLUMNINFO
18604  *
18605  GetColumnInfo
18606  (T * pv,
18607  DBORDINAL *
18608  pcCols) \
18609  {
18610  \
18611 pv;
18612  \
18613 static ATL::
18614  ATLCOLUMNINFO
18615  _rgColumns[] =
18616  \
18617  {
18618 
18619 
18620 #define SIZEOF_MEMBER(memberOf, member) \
18621  sizeof (((memberOf *) 0)->member)
18622 #define EXPANDGUID(guid) \
18623  {
18624  guid.Data1,
18625  guid.Data2,
18626  guid.Data3, \
18627  {
18628  guid.Data4[0],
18629  guid.Data4[1],
18630  guid.Data4[2],
18631  guid.Data4[3],
18632  guid.Data4[4],
18633  guid.Data4[5],
18634  guid.Data4[6],
18635  guid.Data4[7]}
18636  }
18637 
18638 
18639 #define PROVIDER_COLUMN_ENTRY_GN(name, ordinal, flags, colSize, dbtype, precision, scale, guid) \
18640  {
18641  (LPOLESTR)
18642  name,
18643  (ITypeInfo *)
18644  NULL,
18645  (DBORDINAL)
18646  ordinal,
18647  (DBCOLUMNFLAGS)
18648  flags,
18649  (DBLENGTH)
18650  colSize,
18651  (DBTYPE)
18652  dbtype,
18653  (BYTE)
18654  precision,
18655  (BYTE) scale,
18656  {
18657  EXPANDGUID
18658  (guid),
18659  (DWORD) 0,
18660  (LPOLESTR)
18661  name}
18662  , 0}
18663  ,
18664 
18665 #define PROVIDER_COLUMN_ENTRY_EX(name, typeinfo, ordinal, flags, colSize, dbtype, precision, scale, guid, member) \
18666  {
18667  \
18668 (LPOLESTR)
18669  OLESTR (name),
18670  \
18671 typeinfo,
18672  \
18673 (DBORDINAL)
18674  ordinal,
18675  \
18676 flags,
18677  \
18678 colSize,
18679  \
18680 dbtype,
18681  \
18682 (BYTE)
18683  precision,
18684  \
18685 (BYTE)
18686  scale, \
18687  {
18688  \
18689 EXPANDGUID
18690  (guid),
18691  \
18692 (DWORD)
18693  DBKIND_NAME,
18694  \
18695 (LPOLESTR)
18696  OLESTR (name)
18697  \
18698 }
18699  ,
18700  \
18701 offsetof
18702  (_Class,
18703  member) \
18704 }
18705  ,
18706 
18707 #define PROVIDER_COLUMN_ENTRY(name, ordinal, member) \
18708  PROVIDER_COLUMN_ENTRY_EX
18710  ordinal,
18712  (DBLENGTH)
18714  (_Class,
18715  member),
18716  ATL::
18717  _GetOleDBType
18718  (((_Class *)
18719  0)->
18720  member), 0,
18721  0, GUID_NULL,
18722  member)
18723 
18725  PROVIDER_COLUMN_ENTRY_EX
18726  (name, NULL,
18727  ordinal,
18729  (DBLENGTH)
18731  (_Class,
18732  member),
18733  ATL::
18734  _GetOleDBType
18735  (((_Class *)
18736  0)->
18737  member),
18738  precision,
18739  scale,
18740  GUID_NULL,
18741  member)
18742 
18743 #define PROVIDER_COLUMN_ENTRY_LENGTH(name, ordinal, size, member) \
18744  PROVIDER_COLUMN_ENTRY_EX
18746  ordinal,
18748  size,
18749  ATL::
18750  _GetOleDBType
18751  (((_Class *)
18752  0)->
18753  member), 0,
18754  0, GUID_NULL,
18755  member)
18756 
18758  PROVIDER_COLUMN_ENTRY_EX
18760  ordinal,
18762  size, type,
18763  0, 0,
18764  GUID_NULL,
18765  member)
18766 
18767 #define PROVIDER_COLUMN_ENTRY_TYPE(name, ordinal, type, member) \
18768  PROVIDER_COLUMN_ENTRY_EX
18769  (name, NULL,
18770  ordinal,
18772  (DBLENGTH)
18774  (_Class,
18775  member),
18776  type, 0, 0,
18777  GUID_NULL,
18778  member)
18779 
18781  PROVIDER_COLUMN_ENTRY_EX
18782  (name, NULL,
18783  ordinal,
18785  (DBLENGTH)
18787  (_Class,
18788  member),
18789  type,
18790  precision,
18791  scale,
18792  GUID_NULL,
18793  member)
18794 
18795 #define PROVIDER_COLUMN_ENTRY_FIXED(name, ordinal, type, member) \
18796  PROVIDER_COLUMN_ENTRY_EX
18797  (name, NULL,
18798  ordinal,
18800  (DBLENGTH)
18802  (_Class,
18803  member),
18804  type, 0, 0,
18805  GUID_NULL,
18806  member)
18807 
18809  PROVIDER_COLUMN_ENTRY_EX
18810  (name, NULL,
18811  ordinal, 0,
18812  (DBLENGTH)
18814  (_Class,
18815  member),
18817  255, 255,
18818  GUID_NULL,
18819  member)
18820 
18821 #define PROVIDER_COLUMN_ENTRY_WSTR(name, ordinal, member) \
18822  PROVIDER_COLUMN_ENTRY_EX
18823  (name, NULL,
18824  ordinal, 0,
18825  (DBLENGTH)
18827  (_Class,
18828  member),
18830  255, 255,
18831  GUID_NULL,
18832  member)
18833 
18835  };
18837  sizeof
18838  (_rgColumns) /
18839  sizeof (ATL::
18840  ATLCOLUMNINFO);
18841  return
18843 
18844 
18845 class CDynColumnInfo: public
18846  CAtlArray <
18847  ATLCOLUMNINFO
18848  >
18849  {
18850 
18851 public:
18852 HRESULT
18853  Add (LPOLESTR
18854  szName,
18855  DBORDINAL
18856  ordinal,
18857  DBLENGTH
18858  colSize,
18859 
18860 DBTYPE
18861  type,
18862  BYTE
18863  precision,
18864  BYTE
18865  scale,
18866 
18867 DBBYTEOFFSET
18868  offset,
18869  DWORD
18870  flags =
18872 
18873  {
18874 
18875 ATLCOLUMNINFO
18876  col;
18877 
18878 col.
18879  pwszName =
18880  szName;
18881 
18882 col.
18883  pTypeInfo =
18884  NULL;
18885 
18886 col.
18887  iOrdinal =
18888  ordinal;
18889 
18890 col.dwFlags =
18891  flags;
18892 
18893 col.
18894  ulColumnSize =
18895  colSize;
18896 
18897 col.wType =
18898  type;
18899 
18900 col.
18901  bPrecision =
18902  precision;
18903 
18904 col.bScale =
18905  scale;
18906 
18907 col.
18908  cbOffset =
18909  offset;
18910 
18911 memset (&
18912  (col.
18913  columnid),
18914  0,
18915  sizeof
18916  (DBID));
18917 
18918 col.columnid.
18919  uName.
18920  pwszName =
18921  (LPOLESTR)
18922  szName;
18923 
18924 _ATLTRY
18925  {
18926 
18927 CAtlArray <
18928  ATLCOLUMNINFO
18929  >::Add (col);
18930 
18931 }
18932 
18933 _ATLCATCH (e)
18934 
18935  {
18936 
18937 _ATLDELETEEXCEPTION
18938  (e);
18939 
18940 return
18941  E_OUTOFMEMORY;
18942 
18943 }
18944 
18945 return S_OK;
18946 }
18947 
18948 
18949 HRESULT
18950  AddString
18951  (LPOLESTR
18952  szName,
18953  DBORDINAL
18954  ordinal,
18955  DBLENGTH
18956  colSize,
18957  DBBYTEOFFSET
18958  offset)
18959  {
18960 
18961 return
18962  Add (szName,
18963  ordinal,
18964  colSize,
18965  DBTYPE_STR,
18966  0xFF,
18967  0xFF,
18968  offset);
18969 
18970 }
18971 
18972 };
18973 
18974 
18975 // Implementation Class
18976  class
18977  CSimpleRow
18978  {
18979 
18980 public:
18981 typedef
18982  DBCOUNTITEM
18984 
18985 
18986 CSimpleRow
18987  (DBCOUNTITEM
18988  iRowsetCur)
18989  {
18990 
18991 m_dwRef = 0;
18992 m_pData = NULL;
18993 m_iRowset = iRowsetCur;
18994 m_iOriginalRowset = iRowsetCur; // used
18995  // for
18996  // stronger
18997  // identity
18998  // tests
18999  m_status = 0;
19000 }
19001 
19002 ~CSimpleRow
19003  ()
19004  {
19005 
19006 m_pData = NULL; // Data
19007  // will
19008  // be
19009  // freed
19010  // seperately
19011  }
19012 DWORD
19014  {
19015  return
19016  CComObjectThreadModel::
19017  Increment ((LPLONG) & m_dwRef);}
19018 
19019 DWORD
19021  {
19022  return
19023  CComObjectThreadModel::
19024  Decrement ((LPLONG) & m_dwRef);}
19025 
19026 
19027 HRESULT
19028  Compare
19030  pRow)
19031  {
19032 
19033 ATLASSERT
19034  (pRow !=
19035  NULL);
19036 
19037 return
19038  (m_iRowset ==
19039  pRow->
19040  m_iRowset) ?
19041  S_OK :
19042  S_FALSE;
19043 }
19044 
19045 
19046 DWORD m_dwRef;
19047 void *m_pData; // NEW:
19048  // For
19049  // IRowsetChange
19050  // &
19051  // IRowsetUpdate
19052  DBPENDINGSTATUS m_status; // NEW:
19053  // For
19054  // IRowsetUpdate
19055  KeyType m_iOriginalRowset; // NEW:
19056  // For
19057  // IRowsetChange
19058  // &
19059  // IRowsetUpdate
19060  KeyType
19061  m_iRowset;
19062 };
19063 
19064 
19065 template <
19066  class T >
19067 
19068 inline void
19070  (T * pT,
19071  HROW
19072  hNotifyRow,
19073  T::
19074  _BindType *
19075  pBinding,
19076 
19077 CAtlArray <
19078  DBORDINAL >
19079  &rgColumns)
19080  {
19081 
19082 pT->
19083  Fire_OnFieldChange
19084  (pT,
19085  hNotifyRow,
19086  pBinding->
19087  cBindings,
19088 
19089 rgColumns.
19090  GetData (),
19091  DBREASON_COLUMN_SET,
19092 
19093 DBEVENTPHASE_FAILEDTODO,
19094  TRUE);
19095 
19096 }
19097 
19098 template
19099  < class T,
19100  class RowClass
19101  >
19102 
19103 inline void
19105  (T * pT,
19106  RowClass *
19107  pRow,
19108  HROW *
19109  phNotifyRow,
19110  bool
19111  bDeferred)
19112  {
19113 
19114 if
19115  (bDeferred)
19116  {
19117 
19118  // Determine
19119  // if we are
19120  // really in
19121  // a first
19122  // row change
19123  //
19124  if (pRow->
19125  m_status
19126  !=
19127  DBPENDINGSTATUS_CHANGED
19128  &&
19129 pRow->
19130  m_status
19131  !=
19132  (DBPENDINGSTATUS_NEW
19133  |
19134  DBPENDINGSTATUS_UNCHANGED))
19135 
19136  {
19137 
19138 pT->
19139  Fire_OnRowChange
19140  (pT, 1,
19141  phNotifyRow,
19142 
19143 DBREASON_ROW_FIRSTCHANGE,
19144  DBEVENTPHASE_FAILEDTODO,
19145  TRUE);
19146 }
19147 
19148 }
19149 
19150 }
19151 
19152 
19153 template < class T, class RowClass, class MapClass >
19154 HRESULT TransferData (T * pT, bool bReading, void *pData,
19155 RowClass * pRow, MapClass * /* pMap
19156  */
19157  ,
19158  HACCESSOR
19159  hAccessor)
19160 
19161  {
19162 
19163 ATLTRACE
19164  (atlTraceDBProvider,
19165  2,
19166  _T
19167  ("TransferData\n"));
19168 
19169 bool bFailed
19170  = false;
19171 
19172 bool
19173  bSucceeded =
19174  false;
19175 
19176 HRESULT hr =
19177  S_OK;
19178 
19179 
19180 __if_exists
19181  (T::
19182  Fire_OnFieldChange)
19183 
19184  {
19185 
19186 CAtlArray <
19187  DBORDINAL >
19188  rgColumns;
19189 
19190 HROW
19191  hNotifyRow =
19192  NULL;
19193  // HROW
19194  // hNotifyRow
19195  // =
19196  // pT->m_rgRowHandles.ReverseLookup(pRow);
19197  {
19198 
19199 POSITION pos
19200  =
19201  pT->
19202  m_rgRowHandles.
19203  GetStartPosition
19204  ();
19205 
19206 while (pos !=
19207  NULL)
19208 
19209  {
19210 
19211 MapClass::
19212  CPair *
19213  pPair =
19214  pT->
19215  m_rgRowHandles.
19216  GetNext (pos);
19217 
19218 ATLASSERT
19219  (pPair !=
19220  NULL);
19221 
19222 if (pPair->
19223  m_value
19224  ==
19225  pRow)
19226  {
19227 
19228 hNotifyRow =
19229  pPair->m_key;
19230 
19231 break;
19232 }
19233 
19234 }
19235 
19236 }
19237 
19238 }
19239 
19240 
19241 __if_exists
19242  (T::
19243  Fire_OnRowChange)
19244 
19245  {
19246 
19247  // We need to
19248  // send the
19249  // DBREASON_ROW_FIRSTCHANGE
19250  // notification's
19251  // SYNCHAFTER
19252  // phase in
19253  // this
19254  // function.
19255  // IFF. we're
19256  // deferred
19257  // and
19258  // we have a
19259  // newly
19260  // changed
19261  // row.
19262 
19263 CComVariant
19264  varDeferred;
19265 
19266 bool
19267  bDeferred;
19268 
19269 hr =
19270  pT->
19271  GetPropValue
19272  (&DBPROPSET_ROWSET,
19273  DBPROP_IRowsetUpdate,
19274 
19275 &varDeferred);
19276 
19277 (FAILED (hr)
19278  ||
19279  varDeferred.
19280  boolVal ==
19282  ? bDeferred =
19283  false :
19284  bDeferred =
19285  true;
19286 }
19287 
19288 
19289  // Check for
19290  // a deleted
19291  // row
19292  if (pRow->
19293  m_iRowset
19294  >=
19295  pT->
19296  m_rgRowData.
19297  GetCount
19298  ())
19299  {
19300 
19301 __if_exists
19302  (T::
19303  Fire_OnFieldChange)
19304 
19305  {
19306 
19307 if
19308  (!bReading)
19309  {
19310 
19312  (pT, pRow,
19313  &hNotifyRow,
19314  bDeferred);
19315 
19316 }
19317 
19318 }
19319 
19320 return
19321  DB_E_DELETEDROW;
19322 
19323 }
19324 
19325 
19326  // NOTE: This
19327  // was
19328  // checking
19329  // against
19330  // DBPENDINGSTATUS_DELETED.
19331  // Instead,
19332  // it
19333  // should
19334  // check for
19335  // DBPENDINGSTATUS_INVALIDROW
19336  // (means a
19337  // forced
19338  // deleted
19339  // row).
19340 
19341 if (pRow->
19342  m_status
19343  ==
19344  DBPENDINGSTATUS_INVALIDROW)
19345 
19346  {
19347 
19348 __if_exists
19349  (T::
19350  Fire_OnFieldChange)
19351 
19352  {
19353 
19354 if
19355  (!bReading)
19356  {
19357 
19359  (pT, pRow,
19360  &hNotifyRow,
19361  bDeferred);
19362 
19363 }
19364 
19365 }
19366 
19367 return
19368  DB_E_DELETEDROW;
19369 
19370 }
19371 
19372 
19373 T::
19374  _BindType *
19375  pBinding;
19376 
19377 bool bFound =
19378  pT->
19379  m_rgBindings.
19380  Lookup ((INT_PTR) hAccessor, pBinding);
19381 if (!bFound || pBinding == NULL)
19382  {
19383 
19384 __if_exists
19385  (T::
19386  Fire_OnFieldChange)
19387 
19388  {
19389 
19390 if
19391  (!bReading)
19392  {
19393 
19395  (pT, pRow,
19396  &hNotifyRow,
19397  bDeferred);
19398 
19399 }
19400 
19401 }
19402 
19403 return
19404  DB_E_BADACCESSORHANDLE;
19405 
19406 }
19407 
19408 
19409 if (pData ==
19410  NULL
19411  &&
19412  pBinding->
19413  cBindings
19414  != 0)
19415  {
19416 
19417 __if_exists
19418  (T::
19419  Fire_OnFieldChange)
19420 
19421  {
19422 
19423 if
19424  (!bReading)
19425  {
19426 
19428  (pT, pRow,
19429  &hNotifyRow,
19430  bDeferred);
19431 
19432 }
19433 
19434 }
19435 
19436 return
19437  E_INVALIDARG;
19438 
19439 }
19440 
19441 
19442 void
19443  *pDstData;
19444 
19445 void
19446  *pSrcData;
19447 
19448 if (bReading)
19449 
19450  {
19451 
19452 pDstData =
19453  pData;
19454 
19455 pSrcData =
19456  (void *)
19457  &(pT->
19458  m_rgRowData[(LONG) pRow->m_iRowset]);
19459 }
19460  else
19461 
19462  {
19463 
19464 pSrcData =
19465  pData;
19466 
19467 pDstData =
19468  (void *)
19469  &(pT->
19470  m_rgRowData[(LONG) pRow->m_iRowset]);
19471 }
19472 
19473 if (!bReading)
19474  {
19475 
19476  // Send the
19477  // OKTODO
19478  // notification
19479  __if_exists
19480  (T::
19481  Fire_OnFieldChange)
19482 
19483  {
19484 
19485 if ( /* pRow->m_status
19486  * !=
19487  * DBPENDINGSTATUS_NEW
19488  * && */
19489  pRow->
19490  m_status
19491  !=
19492  (DBPENDINGSTATUS_NEW
19493  |
19494  DBPENDINGSTATUS_UNCHANGED))
19495 
19496  {
19497 
19498 HRESULT
19499  hrNotify;
19500 
19501 for
19502  (DBORDINAL l =
19503  0;
19504  l <
19505  pBinding->
19506  cBindings;
19507  l++)
19508  {
19509 
19510 _ATLTRY
19511  {
19512 
19513 rgColumns.
19514  Add
19515  (pBinding->
19516  pBindings[l].
19517  iOrdinal);
19518 }
19519 
19520 _ATLCATCH (e)
19521 
19522  {
19523 
19524 _ATLDELETEEXCEPTION
19525  (e);
19526 
19527 return
19528  E_FAIL;
19529 }
19530 
19531 }
19532 
19533 
19534 hrNotify =
19535  pT->
19536  Fire_OnFieldChange
19537  (pT,
19538  hNotifyRow,
19539  pBinding->
19540  cBindings,
19541 
19542 rgColumns.
19543  GetData (),
19544  DBREASON_COLUMN_SET,
19545 
19546 DBEVENTPHASE_OKTODO,
19547  FALSE);
19548 
19549 if ((hrNotify
19550  != S_OK)
19551  &&
19552  (hrNotify
19553  !=
19554  E_FAIL))
19555 
19556  {
19557 
19558 __if_exists
19559  (T::
19560  Fire_OnRowChange)
19561 
19562  {
19563 
19564 if
19565  (bDeferred)
19566  pT->
19567  Fire_OnRowChange
19568  (pT, 1,
19569  &hNotifyRow,
19570 
19571 DBREASON_ROW_FIRSTCHANGE,
19572  DBEVENTPHASE_FAILEDTODO,
19573  TRUE);
19574 
19575 return
19576  DB_E_CANCELED;
19577 
19578 }
19579 
19580 }
19581 
19582 
19583 hrNotify =
19584  pT->
19585  Fire_OnFieldChange
19586  (pT,
19587  hNotifyRow,
19588  pBinding->
19589  cBindings,
19590 
19591 rgColumns.
19592  GetData (),
19593  DBREASON_COLUMN_SET,
19594  DBEVENTPHASE_ABOUTTODO,
19595 
19596 FALSE);
19597 
19598 if ((hrNotify
19599  != S_OK)
19600  &&
19601  (hrNotify
19602  !=
19603  E_FAIL))
19604 
19605  {
19606 
19607 __if_exists
19608  (T::
19609  Fire_OnRowChange)
19610 
19611  {
19612 
19613 if
19614  (bDeferred)
19615  pT->
19616  Fire_OnRowChange
19617  (pT, 1,
19618  &hNotifyRow,
19619 
19620 DBREASON_ROW_FIRSTCHANGE,
19621  DBEVENTPHASE_FAILEDTODO,
19622  TRUE);
19623 
19624 return
19625  DB_E_CANCELED;
19626 
19627 }
19628 
19629 }
19630 
19631 
19632 hrNotify =
19633  pT->
19634  Fire_OnFieldChange
19635  (pT,
19636  hNotifyRow,
19637  pBinding->
19638  cBindings,
19639 
19640 rgColumns.
19641  GetData (),
19642  DBREASON_COLUMN_SET,
19643 
19644 DBEVENTPHASE_SYNCHAFTER,
19645  FALSE);
19646 
19647 if ((hrNotify
19648  != S_OK)
19649  &&
19650  (hrNotify
19651  !=
19652  E_FAIL))
19653 
19654  {
19655 
19656 __if_exists
19657  (T::
19658  Fire_OnRowChange)
19659 
19660  {
19661 
19662 if
19663  (bDeferred)
19664  pT->
19665  Fire_OnRowChange
19666  (pT, 1,
19667  &hNotifyRow,
19668 
19669 DBREASON_ROW_FIRSTCHANGE,
19670  DBEVENTPHASE_FAILEDTODO,
19671  TRUE);
19672 
19673 return
19674  DB_E_CANCELED;
19675 
19676 }
19677 
19678 }
19679 
19680 }
19681 
19682 }
19683 
19684 
19685 __if_exists
19686  (T::
19687  Fire_OnRowChange)
19688 
19689  {
19690 
19691 if (bDeferred
19692  && pRow->
19693  m_status
19694  !=
19695  DBPENDINGSTATUS_CHANGED
19696  &&
19697 
19698 pRow->
19699  m_status
19700  !=
19701  (DBPENDINGSTATUS_NEW
19702  |
19703  DBPENDINGSTATUS_UNCHANGED))
19704 
19705  {
19706 
19707 HRESULT
19708  hrNotify =
19709  pT->
19710  Fire_OnRowChange
19711  (pT, 1,
19712  &hNotifyRow,
19713 
19714 DBREASON_ROW_FIRSTCHANGE,
19715  DBEVENTPHASE_SYNCHAFTER,
19716  FALSE);
19717 
19718 
19719 if ((hrNotify != S_OK) && (hrNotify != E_FAIL))
19720  {
19721 
19722 __if_exists
19723  (T::
19724  Fire_OnFieldChange)
19725 
19726  {
19727 
19728 pT->
19729  Fire_OnFieldChange
19730  (pT,
19731  hNotifyRow,
19732  pBinding->
19733  cBindings,
19734 
19735 rgColumns.
19736  GetData (),
19737  DBREASON_COLUMN_SET,
19738 
19739 DBEVENTPHASE_FAILEDTODO,
19740  TRUE);
19741 }
19742 
19743 return
19744  DB_E_CANCELED;
19745 
19746 }
19747 
19748 }
19749 
19750 }
19751 
19752 }
19753 
19754 
19755 
19756 DBORDINAL
19757  cCols;
19758 
19759 ATLCOLUMNINFO
19760  * pColInfo =
19761  T::
19762  GetColumnInfo
19763  (pT, &cCols);
19764 
19765 for
19766  (DBORDINAL
19767  iBind = 0;
19768  iBind <
19769  pBinding->
19770  cBindings;
19771  iBind++)
19772  {
19773 
19774 DBBINDING *
19775  pBindCur =
19776  &(pBinding->
19777  pBindings
19778  [iBind]);
19779 
19780 DBORDINAL
19781  iColInfo;
19782 
19783 for (iColInfo
19784  = 0;
19785 
19786 iColInfo
19787  < cCols
19788  &&
19789  pBindCur->
19790  iOrdinal
19791  !=
19792  pColInfo
19793  [iColInfo].
19794  iOrdinal;
19795 
19796 iColInfo++);
19797 
19798 if (iColInfo
19799  ==
19800  cCols)
19801  {
19802 
19803 __if_exists
19804  (T::
19805  Fire_OnFieldChange)
19806 
19807  {
19808 
19809 if
19810  (!bReading)
19811  {
19812 
19814  (pT,
19815  hNotifyRow,
19816  pBinding,
19817  rgColumns);
19818 
19820  (pT, pRow,
19821  &hNotifyRow,
19822  bDeferred);
19823 
19824 }
19825 
19826 }
19827 
19828 return
19829  DB_E_BADORDINAL;
19830 
19831 }
19832 
19833 ATLCOLUMNINFO
19834  * pColCur =
19835  &(pColInfo
19836  [iColInfo]);
19837 
19838  // Ordinal
19839  // found at
19840  // iColInfo
19841 
19842 BYTE *
19843  pSrcTemp =
19844  (bReading)
19845  ? (BYTE *)
19846  pSrcData +
19847  pColCur->
19848  cbOffset :
19849 
19850 (BYTE *)
19851  pSrcData +
19852  pBindCur->
19853  obValue;
19854 
19855 
19856 BYTE *
19857  pDstTemp =
19858  NULL;
19859 
19860 if
19861  (pBindCur->
19862  dwPart &
19863  DBPART_VALUE)
19864 
19865  pDstTemp =
19866  (bReading)
19867  ? (BYTE *)
19868  pDstData +
19869  pBindCur->
19870  obValue :
19871 
19872 (BYTE *)
19873  pDstData +
19874  pColCur->
19875  cbOffset;
19876 
19877 
19878 
19879 if
19880  (!bReading)
19881  {
19882 
19883  // Check to
19884  // see that
19885  // the
19886  // appropriate
19887  // data parts
19888  // are
19889  // available
19890  if ((pBindCur->dwPart & DBPART_LENGTH) &&
19891 !(pBindCur->dwPart & DBPART_VALUE) &&
19892 !(pBindCur->dwPart & DBPART_STATUS))
19893  {
19894 
19895 __if_exists
19896  (T::
19897  Fire_OnFieldChange)
19898 
19899  {
19900 
19901 if ( /* pRow->m_status
19902  * !=
19903  * DBPENDINGSTATUS_NEW
19904  * && */
19905  pRow->
19906  m_status
19907  !=
19908  (DBPENDINGSTATUS_NEW
19909  |
19910  DBPENDINGSTATUS_UNCHANGED))
19911 
19912  {
19913 
19914 pT->
19915  Fire_OnFieldChange
19916  (pT,
19917  hNotifyRow,
19918  pBinding->
19919  cBindings,
19920 
19921 rgColumns.
19922  GetData (),
19923  DBREASON_COLUMN_SET,
19924  DBEVENTPHASE_FAILEDTODO,
19925 
19926 TRUE);
19927 }
19928 
19929 }
19930 
19931 
19932  // Not sure
19933  // why you
19934  // would want
19935  // to run
19936  // SetData
19937  // here!
19938  bFailed =
19939  true;
19940 
19941 continue;
19942 }
19943 
19944 }
19945 
19946 
19947  // Handle the
19948  // the status
19949  // for any
19950  // consumer
19951  // issues
19952  DBSTATUS
19953  dbStat =
19954  DBSTATUS_S_OK;
19955 
19956 if (bReading)
19957 
19958  {
19959 
19960 dbStat =
19961  pT->
19962  GetDBStatus
19963  (pRow,
19964  pColCur);
19965 
19966 
19967 if (dbStat
19968  ==
19969  DBSTATUS_S_ISNULL)
19970 
19971  {
19972 
19973 if
19974  (pBindCur->
19975  dwPart &
19976  DBPART_STATUS)
19977 
19978  *((DBSTATUS
19979  *) ((BYTE
19980  *)
19981  (pDstData)
19982  +
19983  pBindCur->
19984  obStatus))
19985  = dbStat;
19986 
19987  // Set the
19988  // length to
19989  // 0 as
19990  // reqiured
19991  // by the
19992  // spec.
19993  if (pBindCur->
19994  dwPart &
19995  DBPART_LENGTH)
19996 
19997  *((DBLENGTH
19998  *) ((BYTE
19999  *)
20000  (pDstData)
20001  +
20002  pBindCur->
20003  obLength))
20004  = 0;
20005 
20006  // Set the
20007  // destination
20008  // value to
20009  // NULL
20010  if (pBindCur->
20011  dwPart &
20012  DBPART_VALUE)
20013 
20014  *pDstTemp =
20015  NULL;
20016 
20017 
20018 continue;
20019 }
20020 
20021 }
20022 
20023  else
20024 
20025  {
20026 
20027  // Allow the
20028  // provider
20029  // to do
20030  // checking
20031  // for
20032  // DBSTATUS_S_ISNULL
20033  if (pBindCur->
20034  dwPart &
20035  DBPART_STATUS)
20036 
20037  {
20038 
20039 dbStat =
20040  *((DBSTATUS
20041  *) ((BYTE
20042  *)
20043  (pSrcData)
20044  +
20045  pBindCur->
20046  obStatus));
20047 
20048 
20049  // Return
20050  // DBSTATUS_E_UNAVAILABLE
20051  // if the
20052  // status is
20053  // DBSTATUS_S_OK
20054  // and either
20055  // the value
20056  // part is
20057  // not bound
20058  // or the
20059  // length
20060  // part is
20061  // bound and
20062  // the type
20063  // is
20064  // DBTYPE_BYTES.
20065 
20066  // There was
20067  // another
20068  // entry of
20069  // code here
20070  // with
20071  // LENGTH, NO
20072  // VALUE,
20073  // and status
20074  // was not
20075  // DBSTATUS_S_ISNULL.
20076  // May need
20077  // to
20078  // regenerate
20079  // that
20080  if (dbStat ==
20081  DBSTATUS_S_OK)
20082 
20083  {
20084 
20085 if (!
20086  (pBindCur->
20087  dwPart &
20088  DBPART_VALUE)
20089  ||
20090 
20091 ((pBindCur->dwPart & DBPART_LENGTH) && (pBindCur->wType == DBTYPE_BYTES)))
20092  {
20093 
20094  // Can't set
20095  // non-null
20096  // columns
20097  // w/o a
20098  // value
20099  // part
20100  __if_exists
20101  (T::
20102  Fire_OnFieldChange)
20103 
20104  {
20105 
20106 if ( /* pRow->m_status
20107  * !=
20108  * DBPENDINGSTATUS_NEW
20109  * && */
20110  pRow->
20111  m_status
20112  !=
20113  (DBPENDINGSTATUS_NEW
20114  |
20115  DBPENDINGSTATUS_UNCHANGED))
20116 
20117  {
20118 
20119 pT->
20120  Fire_OnFieldChange
20121  (pT,
20122  hNotifyRow,
20123  pBinding->
20124  cBindings,
20125 
20126 rgColumns.
20127  GetData (),
20128  DBREASON_COLUMN_SET,
20129  DBEVENTPHASE_FAILEDTODO,
20130 
20131 TRUE);
20132 }
20133 
20134 }
20135 
20136 
20137 bFailed =
20138  true;
20139 
20140 *((DBSTATUS
20141  *) ((BYTE
20142  *)
20143  (pSrcData)
20144  +
20145  pBindCur->
20146  obStatus))
20147  =
20148  DBSTATUS_E_UNAVAILABLE;
20149 
20150 continue;
20151 }
20152 
20153 }
20154 
20155 
20156 switch
20157  (dbStat)
20158  {
20159 
20160 case DBSTATUS_S_ISNULL:
20161 
20162 if (!
20163  (pColCur->
20164  dwFlags
20165  &
20166  DBCOLUMNFLAGS_ISNULLABLE)
20167  ||
20168 
20169 FAILED
20170  (pT->
20171  SetDBStatus
20172  (&dbStat,
20173  pRow,
20174  pColCur)))
20175 
20176  {
20177 
20178 __if_exists
20179  (T::
20180  Fire_OnFieldChange)
20181 
20182  {
20183 
20184 if ( /* pRow->m_status
20185  * !=
20186  * DBPENDINGSTATUS_NEW
20187  * && */
20188  pRow->
20189  m_status
20190  !=
20191  (DBPENDINGSTATUS_NEW
20192  |
20193  DBPENDINGSTATUS_UNCHANGED))
20194 
20195  {
20196 
20197 pT->
20198  Fire_OnFieldChange
20199  (pT,
20200  hNotifyRow,
20201 
20202 pBinding->
20203  cBindings,
20204  rgColumns.
20205  GetData (),
20206 
20207 DBREASON_COLUMN_SET,
20208  DBEVENTPHASE_FAILEDTODO,
20209 
20210 TRUE);
20211 }
20212 
20213 }
20214 
20215 
20216  // Special
20217  // processing
20218  // for
20219  // attempting
20220  // to write,
20221  // read-only
20222  // columns
20223  if (!
20224  (pColCur->
20225  dwFlags &
20226  DBCOLUMNFLAGS_ISNULLABLE))
20227 
20228  *((DBSTATUS
20229  *) ((BYTE
20230  *)
20231  (pSrcData)
20232  +
20233  pBindCur->
20234  obStatus))
20235  =
20236  DBSTATUS_E_INTEGRITYVIOLATION;
20237 
20238 
20239 bFailed =
20240  true;
20241 }
20242 
20243  else
20244 
20245  {
20246 
20247 __if_exists
20248  (T::
20249  Fire_OnFieldChange)
20250 
20251  {
20252 
20253 if ( /* pRow->m_status
20254  * !=
20255  * DBPENDINGSTATUS_NEW
20256  * && */
20257  pRow->
20258  m_status
20259  !=
20260  (DBPENDINGSTATUS_NEW
20261  |
20262  DBPENDINGSTATUS_UNCHANGED))
20263 
20264  {
20265 
20266 pT->
20267  Fire_OnFieldChange
20268  (pT,
20269  hNotifyRow,
20270  1, &iBind,
20271 
20272 DBREASON_COLUMN_SET,
20273  DBEVENTPHASE_DIDEVENT,
20274  TRUE);
20275 }
20276 
20277 }
20278 
20279 bSucceeded =
20280  true;
20281 
20282 dbStat =
20283  DBSTATUS_S_OK;
20284 
20285 if
20286  (pBindCur->
20287  dwPart &
20288  DBPART_VALUE)
20289 
20290  *pDstTemp =
20291  NULL;
20292 }
20293 
20294 continue;
20295 break;
20296 case DBSTATUS_S_DEFAULT:
20297 
20298 case DBSTATUS_S_IGNORE:
20299 
20300  {
20301 
20302 HRESULT
20303  hrStatus =
20304  pT->
20305  SetDBStatus
20306  (&dbStat,
20307  pRow,
20308  pColCur);
20309 
20310 *((DBSTATUS
20311  *) ((BYTE
20312  *)
20313  (pSrcData)
20314  +
20315  pBindCur->
20316  obStatus))
20317  = dbStat;
20318 
20319 
20320 if (FAILED
20321  (hrStatus))
20322 
20323  {
20324 
20325 __if_exists
20326  (T::
20327  Fire_OnFieldChange)
20328 
20329  {
20330 
20331 if ( /* pRow->m_status
20332  * !=
20333  * DBPENDINGSTATUS_NEW
20334  * && */
20335  pRow->
20336  m_status
20337  !=
20338  (DBPENDINGSTATUS_NEW
20339  |
20340  DBPENDINGSTATUS_UNCHANGED))
20341 
20342  {
20343 
20344 pT->
20345  Fire_OnFieldChange
20346  (pT,
20347  hNotifyRow,
20348  pBinding->
20349  cBindings,
20350 
20351 rgColumns.
20352  GetData (),
20353  DBREASON_COLUMN_SET,
20354 
20355 DBEVENTPHASE_FAILEDTODO,
20356  TRUE);
20357 }
20358 
20359 }
20360 
20361 
20362  // Note,
20363  // status
20364  // should be
20365  // set by
20366  // SetDBStatus
20367  bFailed =
20368  true;
20369 }
20370 
20371  else
20372 
20373  {
20374 
20375 __if_exists
20376  (T::
20377  Fire_OnFieldChange)
20378 
20379  {
20380 
20381 if ( /* pRow->m_status
20382  * !=
20383  * DBPENDINGSTATUS_NEW
20384  * && */
20385  pRow->
20386  m_status
20387  !=
20388  (DBPENDINGSTATUS_NEW
20389  |
20390  DBPENDINGSTATUS_UNCHANGED))
20391 
20392  {
20393 
20394 pT->
20395  Fire_OnFieldChange
20396  (pT,
20397  hNotifyRow,
20398  pBinding->
20399  cBindings,
20400 
20401 rgColumns.
20402  GetData (),
20403  DBREASON_COLUMN_SET,
20404 
20405 DBEVENTPHASE_DIDEVENT,
20406  TRUE);
20407 }
20408 
20409 }
20410 
20411 bSucceeded =
20412  true;
20413 }
20414 
20415 continue;
20416 
20417 break;
20418 }
20419 
20420 case DBSTATUS_S_OK:
20421 
20422  // Still call
20423  // SetDBStatus
20424  // here as
20425  // they may
20426  // have locks
20427  // on
20428  // integrity
20429  // contstraints
20430  // to
20431  // observe
20432  if (FAILED
20433  (pT->
20434  SetDBStatus
20435  (&dbStat,
20436  pRow,
20437  pColCur)))
20438 
20439  {
20440 
20441 __if_exists
20442  (T::
20443  Fire_OnFieldChange)
20444 
20445  {
20446 
20447 if ( /* pRow->m_status
20448  * !=
20449  * DBPENDINGSTATUS_NEW
20450  * && */
20451  pRow->
20452  m_status
20453  !=
20454  (DBPENDINGSTATUS_NEW
20455  |
20456  DBPENDINGSTATUS_UNCHANGED))
20457 
20458  {
20459 
20460 pT->
20461  Fire_OnFieldChange
20462  (pT,
20463  hNotifyRow,
20464  pBinding->
20465  cBindings,
20466 
20467 rgColumns.
20468  GetData (),
20469  DBREASON_COLUMN_SET,
20470 
20471 DBEVENTPHASE_FAILEDTODO,
20472  TRUE);
20473 }
20474 
20475 }
20476 
20477 
20478 bFailed =
20479  true;
20480 
20481 *((DBSTATUS
20482  *) ((BYTE
20483  *)
20484  (pSrcData)
20485  +
20486  pBindCur->
20487  obStatus))
20488  = dbStat;
20489 
20490 continue;
20491 }
20492 
20493 break;
20494 default:
20495 
20496 *((DBSTATUS
20497  *) ((BYTE
20498  *)
20499  (pSrcData)
20500  +
20501  pBindCur->
20502  obStatus))
20503  =
20504  DBSTATUS_E_BADSTATUS;
20505 
20506 
20507 __if_exists
20508  (T::
20509  Fire_OnFieldChange)
20510 
20511  {
20512 
20513 if ( /* pRow->m_status
20514  * !=
20515  * DBPENDINGSTATUS_NEW
20516  * && */
20517  pRow->
20518  m_status
20519  !=
20520  (DBPENDINGSTATUS_NEW
20521  |
20522  DBPENDINGSTATUS_UNCHANGED))
20523 
20524  {
20525 
20526 pT->
20527  Fire_OnFieldChange
20528  (pT,
20529  hNotifyRow,
20530  pBinding->
20531  cBindings,
20532 
20533 rgColumns.
20534  GetData (),
20535  DBREASON_COLUMN_SET,
20536 
20537 DBEVENTPHASE_FAILEDTODO,
20538  TRUE);
20539 }
20540 
20541 }
20542 
20543 
20544 bFailed =
20545  true;
20546 
20547 continue;
20548 
20549 break;
20550 }
20551 
20552 }
20553 
20554 }
20555 
20556 
20557 
20558  // Determine
20559  // sizes of
20560  // input and
20561  // output
20562  // columns
20563  DBLENGTH cbCol
20564  = 0;
20565 
20566 DBLENGTH
20567  cbDst;
20568 
20569 if (bReading)
20570 
20571  cbDst =
20572  pBindCur->
20573  cbMaxLen;
20574  else
20575 
20576 cbDst =
20577  pColCur->
20578  ulColumnSize;
20579 
20580 
20581 switch
20582  (pColCur->
20583  wType)
20584  {
20585 
20586 case DBTYPE_STR:
20587 
20588 if (bReading)
20589 
20590  cbCol =
20591  lstrlenA ((LPSTR) (((BYTE *) pSrcData) + pColCur->cbOffset));
20592  else
20593 
20594  {
20595 
20596  // Use the
20597  // length
20598  // field when
20599  // setting
20600  // data
20601  if (pBindCur->
20602  dwPart &
20603  DBPART_LENGTH)
20604 
20605  cbCol =
20606  *((DBLENGTH
20607  *) ((BYTE
20608  *)
20609  (pSrcData)
20610  +
20611  pBindCur->
20612  obLength));
20613 
20614  else
20615 
20616 cbCol = lstrlenA ((LPSTR) (pSrcTemp)); // was
20617  // cbDst
20618 
20619 if (cbCol >=
20620  cbDst)
20621  {
20622 
20623 if (cbCol > (cbDst + 1)) // over
20624  // maximum
20625  // case
20626  {
20627 
20628 __if_exists
20629  (T::
20630  Fire_OnFieldChange)
20631 
20632  {
20633 
20634 if ( /* pRow->m_status
20635  * !=
20636  * DBPENDINGSTATUS_NEW
20637  * && */
20638  pRow->
20639  m_status
20640  !=
20641  (DBPENDINGSTATUS_NEW
20642  |
20643  DBPENDINGSTATUS_UNCHANGED))
20644 
20645  {
20646 
20647 pT->
20648  Fire_OnFieldChange
20649  (pT,
20650  hNotifyRow,
20651  pBinding->
20652  cBindings,
20653 
20654 rgColumns.
20655  GetData (),
20656  DBREASON_COLUMN_SET,
20657 
20658 DBEVENTPHASE_FAILEDTODO,
20659  TRUE);
20660 }
20661 
20662 }
20663 
20664 
20665 bFailed =
20666  true;
20667 
20668 if
20669  (pBindCur->
20670  dwPart &
20671  DBPART_STATUS)
20672 
20673  *((DBSTATUS
20674  *) ((BYTE
20675  *)
20676  (pSrcData)
20677  +
20678  pBindCur->
20679  obStatus))
20680  =
20681  DBSTATUS_E_CANTCONVERTVALUE;
20682 
20683 continue;
20684 }
20685 
20686 }
20687 
20688 cbCol = cbDst; // Leave
20689  // room
20690  // for
20691  // NULL
20692  // term.
20693  // need
20694  // to
20695  // copy
20696  // for
20697  // WSTR
20698  }
20699 
20700 break;
20701 case DBTYPE_WSTR:
20702 
20703 case DBTYPE_BSTR:
20704 
20705 if (bReading)
20706 
20707  cbCol =
20708  lstrlenW ((LPWSTR) (((BYTE *) pSrcData) + pColCur->cbOffset)) * sizeof (WCHAR);
20709  else
20710 
20711  {
20712 
20713 if
20714  (pBindCur->
20715  dwPart &
20716  DBPART_LENGTH)
20717 
20718  cbCol =
20719  *((DBLENGTH
20720  *) ((BYTE
20721  *)
20722  (pSrcData)
20723  +
20724  pBindCur->
20725  obLength));
20726 
20727  else
20728 
20729 cbCol =
20730  lstrlenW ((LPWSTR) (pSrcData)) * sizeof (WCHAR);
20731 
20732 if (cbCol >= cbDst)
20733  {
20734 
20735 if (cbCol > (cbDst + 1)) // over
20736  // maximum
20737  // case
20738  {
20739 
20740 __if_exists
20741  (T::
20742  Fire_OnFieldChange)
20743 
20744  {
20745 
20746 if ( /* pRow->m_status
20747  * !=
20748  * DBPENDINGSTATUS_NEW
20749  * && */
20750  pRow->
20751  m_status
20752  !=
20753  (DBPENDINGSTATUS_NEW
20754  |
20755  DBPENDINGSTATUS_UNCHANGED))
20756 
20757  {
20758 
20759 pT->
20760  Fire_OnFieldChange
20761  (pT,
20762  hNotifyRow,
20763  pBinding->
20764  cBindings,
20765 
20766 rgColumns.
20767  GetData (),
20768  DBREASON_COLUMN_SET,
20769 
20770 DBEVENTPHASE_FAILEDTODO,
20771  TRUE);
20772 }
20773 
20774 }
20775 
20776 
20777 bFailed =
20778  true;
20779 
20780 if
20781  (pBindCur->
20782  dwPart &
20783  DBPART_STATUS)
20784 
20785  *((DBSTATUS
20786  *) ((BYTE
20787  *)
20788  (pSrcData)
20789  +
20790  pBindCur->
20791  obStatus))
20792  =
20793  DBSTATUS_E_CANTCONVERTVALUE;
20794 
20795 continue;
20796 }
20797 
20798 }
20799 
20800 cbCol = cbDst; // Leave
20801  // room
20802  // for
20803  // NULL
20804  // term.
20805  // need
20806  // to
20807  // copy
20808  // for
20809  // WSTR
20810  }
20811 
20812 break;
20813 case DBTYPE_BYTES:
20814 
20815 if (bReading)
20816 
20817  cbCol =
20818  pColCur->
20819  ulColumnSize;
20820 
20821  else
20822 
20823  {
20824 
20825 if
20826  (pBindCur->
20827  dwPart &
20828  DBPART_LENGTH)
20829 
20830  cbCol =
20831  *((DBLENGTH
20832  *) ((BYTE
20833  *)
20834  (pSrcData)
20835  +
20836  pBindCur->
20837  obLength));
20838 
20839  else
20840 
20841  {
20842 
20843 __if_exists
20844  (T::
20845  Fire_OnFieldChange)
20846 
20847  {
20848 
20849 if ( /* pRow->m_status
20850  * !=
20851  * DBPENDINGSTATUS_NEW
20852  * && */
20853  pRow->
20854  m_status
20855  !=
20856  (DBPENDINGSTATUS_NEW
20857  |
20858  DBPENDINGSTATUS_UNCHANGED))
20859 
20860  {
20861 
20862 pT->
20863  Fire_OnFieldChange
20864  (pT,
20865  hNotifyRow,
20866  pBinding->
20867  cBindings,
20868 
20869 rgColumns.
20870  GetData (),
20871  DBREASON_COLUMN_SET,
20872 
20873 DBEVENTPHASE_FAILEDTODO,
20874  TRUE);
20875 }
20876 
20877 }
20878 
20879 
20880  // If no
20881  // length
20882  // part is
20883  // bound for
20884  // DBTYPE_BYTES,
20885  // it is an
20886  // error
20887  bFailed =
20888  true;
20889 
20890 continue;
20891 }
20892 
20893 
20894 if (cbCol >= cbDst)
20895  cbCol = cbDst; // Leave
20896  // room
20897  // for
20898  // NULL
20899  // term.
20900  // need
20901  // to
20902  // copy
20903  // for
20904  // WSTR
20905  }
20906 
20907 break;
20908 default:
20909 
20910 if (bReading)
20911 
20912  cbCol =
20913  pColCur->
20914  ulColumnSize;
20915 
20916  else
20917 
20918 cbDst =
20919  pColCur->
20920  ulColumnSize;
20921 
20922 
20923 break;
20924 }
20925 
20926 
20927 
20928  // Handle
20929  // cases
20930  // where we
20931  // have
20932  // provider
20933  // owned
20934  // memory.
20935  // Note,
20936  // these
20937  // should be
20938  // with
20939  // DBTYPE_BYREF
20940  // (otherwise,
20941  // it doesn't
20942  // make
20943  // sense).
20944  if (pBindCur->
20945  dwPart &
20946  DBPART_VALUE)
20947 
20948  {
20949 
20950 if
20951  (pBindCur->
20952  dwMemOwner ==
20953  DBMEMOWNER_PROVIDEROWNED
20954 
20955  &&pBindCur->
20956  wType &
20957  DBTYPE_BYREF)
20958 
20959  {
20960 
20961 *(BYTE **)
20962  pDstTemp =
20963  pSrcTemp;
20964 }
20965 
20966  else
20967 
20968  {
20969 
20970 ATLASSERT
20971  (pT->
20972  m_spConvert
20973  != NULL);
20974 
20975 hr =
20976  pT->
20977  m_spConvert->
20978  DataConvert
20979  (pColCur->
20980  wType,
20981  pBindCur->
20982  wType,
20983 
20984 cbCol,
20985  &cbDst,
20986  pSrcTemp,
20987  pDstTemp,
20988  pBindCur->
20989  cbMaxLen,
20990 
20991 dbStat,
20992  &dbStat,
20993  pBindCur->
20994  bPrecision,
20995  pBindCur->
20996  bScale, 0);
20997 
20998 }
20999 
21000 }
21001 
21002 if
21003  (pBindCur->
21004  dwPart &
21005  DBPART_LENGTH)
21006 
21007  {
21008 
21009 if (bReading)
21010 
21011  {
21012 
21013 if (!(pBindCur->dwPart & DBPART_VALUE))
21014  cbDst = cbCol; // We
21015  // didn't
21016  // have
21017  // the
21018  // data
21019  // convert
21020  // to
21021  // correct
21022  // this
21023  *((DBLENGTH
21024  *) ((BYTE
21025  *)
21026  (pDstData)
21027  +
21028  pBindCur->
21029  obLength))
21030  =
21031  (dbStat ==
21032  DBSTATUS_S_ISNULL)
21033  ? 0 : cbDst;
21034 
21035 }
21036 
21037  else
21038 
21039 *((DBLENGTH
21040  *) ((BYTE
21041  *)
21042  (pSrcData)
21043  +
21044  pBindCur->
21045  obLength))
21046  = cbDst;
21047 }
21048 
21049 if
21050  (pBindCur->
21051  dwPart &
21052  DBPART_STATUS)
21053 
21054  {
21055 
21056 if (bReading)
21057 
21058  *((DBSTATUS
21059  *) ((BYTE
21060  *)
21061  (pDstData)
21062  +
21063  pBindCur->
21064  obStatus))
21065  = dbStat;
21066  else
21067 
21068 *((DBSTATUS
21069  *) ((BYTE
21070  *)
21071  (pSrcData)
21072  +
21073  pBindCur->
21074  obStatus))
21075  = dbStat;
21076 }
21077 
21078 
21079 if (FAILED
21080  (hr))
21081  {
21082 
21083 if
21084  (!bReading)
21085  {
21086 
21087 __if_exists
21088  (T::
21089  Fire_OnFieldChange)
21090 
21091  {
21092 
21093 if ( /* pRow->m_status
21094  * !=
21095  * DBPENDINGSTATUS_NEW
21096  * && */
21097  pRow->
21098  m_status
21099  !=
21100  (DBPENDINGSTATUS_NEW
21101  |
21102  DBPENDINGSTATUS_UNCHANGED))
21103 
21104  {
21105 
21106 pT->
21107  Fire_OnFieldChange
21108  (pT,
21109  hNotifyRow,
21110  pBinding->
21111  cBindings,
21112 
21113 rgColumns.
21114  GetData (),
21115  DBREASON_COLUMN_SET,
21116 
21117 DBEVENTPHASE_FAILEDTODO,
21118  TRUE);
21119 }
21120 
21121 }
21122 
21123 }
21124 
21125 
21126 bFailed =
21127  true;
21128 }
21129 
21130  else
21131 
21132  {
21133 
21134 bSucceeded =
21135  true;
21136 }
21137 
21138 }
21139 
21140 
21141  // Return
21142  // error
21143  // codes to
21144  // the
21145  // consumer
21146  if (bFailed)
21147  {
21148 
21149 __if_exists
21150  (T::
21151  Fire_OnFieldChange)
21152 
21153  {
21154 
21155 if
21156  (!bReading)
21157  {
21158 
21159 // SendColumnSetFailureNotification( pT, hNotifyRow, pBinding, rgColumns );
21161  (pT, pRow,
21162  &hNotifyRow,
21163  bDeferred);
21164 
21165 }
21166 
21167 }
21168 
21169 return
21170  (bSucceeded !=
21171  false) ?
21172  DB_S_ERRORSOCCURRED
21173  :
21174  DB_E_ERRORSOCCURRED;
21175 
21176 }
21177 
21178  else
21179 
21180  {
21181 
21182 if
21183  (!bReading)
21184  {
21185 
21186 __if_exists
21187  (T::
21188  Fire_OnFieldChange)
21189 
21190  {
21191 
21192 if ( /* pRow->m_status
21193  * !=
21194  * DBPENDINGSTATUS_NEW
21195  * && */
21196  pRow->
21197  m_status
21198  !=
21199  (DBPENDINGSTATUS_NEW
21200  |
21201  DBPENDINGSTATUS_UNCHANGED))
21202 
21203  {
21204 
21205 pT->
21206  Fire_OnFieldChange
21207  (pT,
21208  hNotifyRow,
21209  pBinding->
21210  cBindings,
21211 
21212 rgColumns.
21213  GetData (),
21214  DBREASON_COLUMN_SET,
21215 
21216 DBEVENTPHASE_DIDEVENT,
21217  TRUE);
21218 }
21219 
21220 }
21221 
21222 }
21223 
21224 
21225 return hr;
21226 }
21227 
21228 }
21229 
21230 
21231 template < class T, class Storage,
21232 class BaseInterface = IRowsetChange,
21233 class RowClass = CSimpleRow,
21234 class MapClass = CAtlMap < RowClass::KeyType, RowClass * >>
21235 class ATL_NO_VTABLE IRowsetChangeImpl:public
21236  BaseInterface
21237 
21238  {
21239 
21240 public:
21241  // IRowsetChange
21242  // Methods
21243  STDMETHOD (DeleteRows) (HCHAPTER /* hReserved
21244  */
21245  ,
21246  DBCOUNTITEM
21247  cRows,
21248 
21249 const
21250  HROW
21251  rghRows
21252  [],
21253  DBROWSTATUS
21254  rgRowStatus
21255  [])
21256 
21257  {
21258 
21259 ATLTRACE
21260  (atlTraceDBProvider,
21261  2,
21262  _T
21263  ("IRowsetChangeImpl::DeleteRows"));
21264 
21265 
21266 T * pT =
21267  (T *) this;
21268 
21269 T::
21270  ObjectLock
21271  lock (pT);
21272 
21273 
21274 __if_exists
21275  (T::
21276  Fire_OnRowChange)
21277 
21278  {
21279 
21280  // Check to
21281  // see if
21282  // someone is
21283  // in an
21284  // event
21285  // handler.
21286  // If we do,
21287  // then
21288  // we should
21289  // return
21290  // DB_E_NOTREENTRANT.
21291  if (!pT->
21292  IncrementMutex
21293  ())
21294  return
21295  DB_E_NOTREENTRANT;
21296 
21297  else
21298 
21299 pT->
21300  DecrementMutex
21301  ();
21302 }
21303 
21304 
21305 BOOL
21306  bSuccess =
21307  false;
21308 
21309 BOOL bFailed
21310  = false;
21311  // Check to
21312  // see if the
21313  // DBPROP_UPDATABILITY
21314  // value
21315  // DBPROPVAL_UP_CHANGE
21316  // is set.
21317  // If not,
21318  // then this
21319  // method
21320  // should
21321  // return
21322  // DB_E_NOTSUPPORTED.
21323  CComVariant
21324  varChange;
21325 
21326 HRESULT hr =
21327  pT->
21328  GetPropValue
21329  (&DBPROPSET_ROWSET,
21330  DBPROP_UPDATABILITY,
21331 
21332 &varChange);
21333 
21334 if (!
21335  (varChange.
21336  iVal &
21338 
21339  return
21340  DB_E_NOTSUPPORTED;
21341 
21342 
21343  // NO-OP if
21344  // cRows is
21345  // zero
21346  if (cRows ==
21347  0)
21348  return S_OK;
21349 
21350 
21351 if (rghRows
21352  == NULL
21353  && cRows
21354  >=
21355  1)
21356  return
21357  E_INVALIDARG;
21358 
21359 
21360  // Determine
21361  // if we're
21362  // in
21363  // immediate
21364  // or
21365  // deferred
21366  // mode
21367  CComVariant
21368  varDeferred;
21369 
21370 bool
21371  bDeferred;
21372 
21373 hr =
21374  pT->
21375  GetPropValue
21376  (&DBPROPSET_ROWSET,
21377  DBPROP_IRowsetUpdate,
21378 
21379 &varDeferred);
21380 
21381 (FAILED (hr)
21382  ||
21383  varDeferred.
21384  boolVal ==
21386  ? bDeferred =
21387  false :
21388  bDeferred =
21389  true;
21390 
21391 
21392  // Loop
21393  // through
21394  // and delete
21395  // rows
21396  for
21397  (DBCOUNTITEM l
21398  = 0;
21399  l < cRows;
21400  l++)
21401  {
21402 
21403 HROW hRow =
21404  rghRows[l];
21405 
21406 RowClass *
21407  pRow;
21408 
21409 DBROWSTATUS
21410  rowStat =
21411  DBROWSTATUS_S_OK;
21412 
21413 
21414  // Handle
21415  // events
21416  __if_exists
21417  (T::
21418  Fire_OnRowChange)
21419 
21420  {
21421 
21422 HRESULT
21423  hrNotify =
21424  pT->
21425  Fire_OnRowChange
21426  (pT, 1,
21427  &rghRows[l],
21428 
21429 DBREASON_ROW_DELETE,
21430  DBEVENTPHASE_OKTODO,
21431  FALSE);
21432 
21433 if (hrNotify
21434  ==
21435  S_FALSE)
21436 
21437  {
21438 
21439 bFailed |=
21440  true;
21441 
21442 if
21443  (rgRowStatus
21444  !=
21445  NULL)
21446  rgRowStatus[l]
21447  =
21448  DBROWSTATUS_E_CANCELED;
21449 
21450 continue;
21451 }
21452 
21453  else
21454 
21455  {
21456 
21457 hrNotify =
21458  pT->
21459  Fire_OnRowChange
21460  (pT, 1,
21461  &rghRows[l],
21462 
21463 DBREASON_ROW_DELETE,
21464  DBEVENTPHASE_ABOUTTODO,
21465  FALSE);
21466 
21467 if (hrNotify
21468  ==
21469  S_FALSE)
21470 
21471  {
21472 
21473 bFailed |=
21474  true;
21475 
21476 if
21477  (rgRowStatus
21478  !=
21479  NULL)
21480  rgRowStatus[l]
21481  =
21482  DBROWSTATUS_E_CANCELED;
21483 
21484 
21485 continue;
21486 }
21487 
21488 }
21489 
21490 
21491  // Send sync
21492  // after now
21493  // as it gets
21494  // tricky to
21495  // replace
21496  // stuff once
21497  //
21498  // we're in
21499  // the
21500  // method.
21501  hrNotify =
21502  pT->
21503  Fire_OnRowChange
21504  (pT, 1,
21505  &rghRows[l],
21506 
21507 DBREASON_ROW_DELETE,
21508  DBEVENTPHASE_SYNCHAFTER,
21509  FALSE);
21510 
21511 if (hrNotify
21512  ==
21513  S_FALSE)
21514 
21515  {
21516 
21517 bFailed |=
21518  true;
21519 
21520 if
21521  (rgRowStatus
21522  !=
21523  NULL)
21524  rgRowStatus[l]
21525  =
21526  DBROWSTATUS_E_CANCELED;
21527 
21528 
21529 continue;
21530 }
21531 
21532 }
21533 
21534 
21535  // Attempt to
21536  // locate the
21537  // row in our
21538  // map
21539  bool bFound =
21540  pT->
21541  m_rgRowHandles.
21542  Lookup (hRow,
21543  pRow);
21544 
21545 if (!bFound
21546  || pRow
21547  ==
21548  NULL)
21549  {
21550 
21551 bFailed |=
21552  true;
21553 
21554 if
21555  (rgRowStatus
21556  !=
21557  NULL)
21558  rgRowStatus[l]
21559  =
21560  DBROWSTATUS_E_INVALID;
21561 
21562 continue;
21563 }
21564 
21565 
21566  // Check if
21567  // the row
21568  // has
21569  // already
21570  // been
21571  // deleted.
21572  // Note, we
21573  // use
21574  // DBPENDINGSTATUS_DELETED
21575  // in the
21576  // immediate
21577  // case as
21578  // well.
21579  if (pRow->
21580  m_status
21581  ==
21582  DBPENDINGSTATUS_DELETED)
21583 
21584  {
21585 
21586 __if_exists
21587  (T::
21588  Fire_OnRowChange)
21589 
21590  {
21591 
21592 pT->
21593  Fire_OnRowChange
21594  (pT, 1,
21595  &rghRows[l],
21596 
21597 DBREASON_ROW_DELETE,
21598  DBEVENTPHASE_FAILEDTODO,
21599 
21600 TRUE);
21601 }
21602 
21603 
21604 if
21605  (rgRowStatus
21606  !=
21607  NULL)
21608  rgRowStatus[l]
21609  =
21610  DBROWSTATUS_E_DELETED;
21611 
21612 bFailed |=
21613  true;
21614 
21615 continue;
21616 }
21617 
21618 
21619 
21620  // Delete the
21621  // row
21622  if (bDeferred)
21623 
21624  {
21625 
21626  // Mark the
21627  // row as
21628  // deleted
21629  // but do not
21630  // remove it
21631  // until
21632  // IRowsetUpdate::Update
21633  // is
21634  // called.
21635  if (pRow->
21636  m_status
21637  !=
21638  DBPENDINGSTATUS_INVALIDROW)
21639 
21640  {
21641 
21642 __if_exists
21643  (T::
21644  Fire_OnRowChange)
21645 
21646  {
21647 
21648 pT->
21649  Fire_OnRowChange
21650  (pT, 1,
21651  &rghRows[l],
21652  DBREASON_ROW_DELETE,
21653 
21654 DBEVENTPHASE_DIDEVENT,
21655  FALSE);
21656 }
21657 
21658 bSuccess |=
21659  true;
21660 
21661 rowStat =
21662  DBROWSTATUS_S_OK;
21663 
21664 }
21665 
21666  else
21667 
21668  {
21669 
21670 __if_exists
21671  (T::
21672  OnRowChange)
21673 
21674  {
21675 
21676 pT->
21677  Fire_OnRowChange
21678  (pT, 1,
21679  &rghRows[l],
21680 
21681 DBREASON_ROW_DELETE,
21682  DBEVENTPHASE_FAILEDTODO,
21683 
21684 FALSE);
21685 }
21686 
21687 
21688 bFailed |=
21689  true;
21690  // unsigned
21691  // high bit
21692  // signified
21693  // neg.
21694  // number
21695  if (pRow->
21696  m_dwRef &
21697  0x80000000)
21698 
21699  rowStat =
21700  DBROWSTATUS_E_INVALID;
21701 
21702  else
21703 
21704 rowStat =
21705  DBROWSTATUS_E_DELETED;
21706 
21707 }
21708 
21709 }
21710 
21711  else
21712 
21713  {
21714 
21715  // Remove the
21716  // m_rgRowData
21717  // and
21718  // m_rgRowLink
21719  // entries.
21720  // The
21721  // HROW will
21722  // be
21723  // released
21724  // in
21725  // IRowset::ReleaseRows.
21726  //
21727  // Remove the
21728  // link by
21729  // NULLing
21730  // out the
21731  // pointer
21732 // if(!pT->m_rgRowData.RemoveAt(pRow->m_iRowset))
21733  if (pRow->
21734  m_iRowset
21735  < 0
21736  || pRow->
21737  m_iRowset
21738  >=
21739  pT->
21740  m_rgRowData.
21741  GetCount
21742  ())
21743  {
21744 
21745 __if_exists
21746  (T::
21747  Fire_OnRowChange)
21748 
21749  {
21750 
21751 pT->
21752  Fire_OnRowChange
21753  (pT, 1,
21754  &rghRows[l],
21755 
21756 DBREASON_ROW_DELETE,
21757  DBEVENTPHASE_FAILEDTODO,
21758 
21759 FALSE);
21760 }
21761 
21762 
21763 rowStat =
21764  DBROWSTATUS_E_INVALID;
21765 
21766 bFailed |=
21767  true;
21768 }
21769 
21770  else
21771 
21772  {
21773 
21774 pT->
21775  m_rgRowData.
21776  RemoveAt
21777  (pRow->
21778  m_iRowset);
21779 
21780 
21781  // Perform
21782  // the actual
21783  // delete of
21784  // the row.
21785  // Send
21786  // notificaitons
21787  // to inform
21788  // the
21789  // consumer
21790  // of the
21791  // change.
21792 
21793  // Need to
21794  // update any
21795  // outstanding
21796  // pRow->m_iRowset
21797  // variables
21798  POSITION pos =
21799  pT->
21800  m_rgRowHandles.
21801  GetStartPosition
21802  ();
21803 
21804 while (pos !=
21805  NULL)
21806 
21807  {
21808 
21809 MapClass::
21810  CPair *
21811  pPair =
21812  pT->
21813  m_rgRowHandles.
21814  GetNext (pos);
21815 
21816 ATLASSERT
21817  (pPair !=
21818  NULL);
21819 
21820 RowClass *
21821  pCheckRow =
21822  pPair->
21823  m_value;
21824 
21825 if (pCheckRow
21826  != NULL
21827  &&
21828 
21829 pCheckRow->
21830  m_iRowset
21831  >
21832  pRow->
21833  m_iRowset)
21834 
21835  pCheckRow->
21836  m_iRowset--;
21837 
21838 }
21839 
21840 
21841 __if_exists
21842  (T::
21843  GetRowsAt)
21844  {
21845 
21846  // If we
21847  // support
21848  // bookmarks,
21849  // then
21850  // ensure our
21851  // bookmark
21852  // array
21853  // is solid
21854  for (size_t k
21855  = 0;
21856  k <
21857  pT->
21858  m_rgBookmarks.
21859  GetCount
21860  ();
21861  k++)
21862  {
21863 
21864 if (pT->m_rgBookmarks[k] == (DBROWCOUNT) (pRow->m_iRowset + 1))
21865  pT->m_rgBookmarks[k] = -1; // Value
21866  // for
21867  // invalid
21868  // bookmark
21869 
21870 if (pT->
21871  m_rgBookmarks
21872  [k] >
21873  (DBROWCOUNT)
21874  (pRow->
21875  m_iRowset
21876  +
21877  1))
21878  pT->
21879  m_rgBookmarks
21880  [k] =
21881  (pT->
21882  m_rgBookmarks
21883  [k] - 1);
21884 }
21885 
21886 }
21887 
21888 
21889 if (FAILED
21890  (pT->
21891  FlushData
21892  (rghRows
21893  [l],
21894  NULL)))
21895 
21896  {
21897 
21898 __if_exists
21899  (T::
21900  Fire_OnRowChange)
21901 
21902  {
21903 
21904 pT->
21905  Fire_OnRowChange
21906  (pT, 1,
21907  &rghRows[l],
21908 
21909 DBREASON_ROW_DELETE,
21910  DBEVENTPHASE_FAILEDTODO,
21911 
21912 FALSE);
21913 }
21914 
21915 bFailed |=
21916  true;
21917 
21918 rowStat =
21919  DBROWSTATUS_E_FAIL;
21920 
21921 }
21922 
21923  else
21924 
21925  {
21926 
21927  // Send
21928  // DIDEVENT
21929  __if_exists
21930  (T::
21931  Fire_OnRowChange)
21932 
21933  {
21934 
21935 pT->
21936  Fire_OnRowChange
21937  (pT, 1,
21938  &rghRows[l],
21939 
21940 DBREASON_ROW_DELETE,
21941  DBEVENTPHASE_DIDEVENT,
21942  FALSE);
21943 }
21944 
21945 rowStat =
21946  DBROWSTATUS_S_OK;
21947 
21948 bSuccess |=
21949  true;
21950 }
21951 
21952 }
21953 
21954 }
21955 
21956 
21957  // We use the
21958  // status
21959  // even in
21960  // immediate
21961  // mode to
21962  // determine
21963  // if a
21964  // row has
21965  // been
21966  // deleted
21967  // from the
21968  // cache but
21969  // not
21970  // release
21971  if (pRow->
21972  m_status
21973  ==
21974  DBPENDINGSTATUS_NEW)
21975 
21976  pRow->
21977  m_status =
21978  DBPENDINGSTATUS_INVALIDROW;
21979 
21980  else
21981 
21982  {
21983 
21984 if (pRow->
21985  m_status
21986  !=
21987  DBPENDINGSTATUS_INVALIDROW)
21988 
21989  pRow->
21990  m_status =
21991  DBPENDINGSTATUS_DELETED;
21992 
21993 }
21994 
21995 
21996 
21997 if
21998  (rgRowStatus
21999  !=
22000  NULL)
22001  rgRowStatus[l]
22002  = rowStat;
22003 }
22004 
22005 
22006 
22007 
22008 hr = S_OK;
22009 
22010 if (bFailed)
22011 
22012  (bSuccess) ?
22013  hr =
22014  DB_S_ERRORSOCCURRED
22015  : hr =
22016  DB_E_ERRORSOCCURRED;
22017 
22018 
22019 return hr;
22020 
22021 }
22022 
22023 
22024 STDMETHOD
22025  (SetData)
22026  (HROW hRow,
22027  HACCESSOR
22028  hAccessor,
22029  void
22030  *pSrcData)
22031  {
22032 
22033 ATLTRACE
22034  (atlTraceDBProvider,
22035  2,
22036  _T
22037  ("IRowsetChangeImpl::SetData\n"));
22038 
22039 
22040 T * pT =
22041  (T *) this;
22042 
22043 T::
22044  ObjectLock
22045  lock (pT);
22046 
22047 
22048 __if_exists
22049  (T::
22050  Fire_OnFieldChange)
22051 
22052  {
22053 
22054  // Check to
22055  // see if
22056  // someone is
22057  // in an
22058  // event
22059  // handler.
22060  // If we do,
22061  // then
22062  // we should
22063  // return
22064  // DB_E_NOTREENTRANT.
22065  if (!pT->
22066  IncrementMutex
22067  ())
22068  return
22069  DB_E_NOTREENTRANT;
22070 
22071  else
22072 
22073 pT->
22074  DecrementMutex
22075  ();
22076 }
22077 
22078 
22079 RowClass *
22080  pRow;
22081 
22082  // Check to
22083  // see if the
22084  // DBPROP_UPDATABILITY
22085  // value
22086  // DBPROPVAL_UP_CHANGE
22087  // is set.
22088  // If not,
22089  // then this
22090  // method
22091  // should
22092  // return
22093  // DB_E_NOTSUPPORTED.
22094  CComVariant
22095  varChange;
22096 
22097 HRESULT hr =
22098  pT->
22099  GetPropValue
22100  (&DBPROPSET_ROWSET,
22101  DBPROP_UPDATABILITY,
22102 
22103 &varChange);
22104 
22105 if (!
22106  (varChange.
22107  iVal &
22108  DBPROPVAL_UP_CHANGE))
22109 
22110  return
22111  DB_E_NOTSUPPORTED;
22112 
22113 
22114 
22115 if (hRow ==
22116  NULL)
22117  return
22118  DB_E_BADROWHANDLE;
22119 
22120 if (!pT->
22121  m_rgRowHandles.
22122  Lookup
22123  (hRow,
22124  pRow))
22125  return
22126  DB_E_BADROWHANDLE;
22127 
22128 if (hRow ==
22129  NULL
22130  || pRow
22131  ==
22132  NULL)
22133  return
22134  DB_E_BADROWHANDLE;
22135 
22136 hr =
22137  TransferData <
22138  T, RowClass,
22139  MapClass >
22140 
22141 (pT, false,
22142  pSrcData,
22143  pRow,
22144  &(pT->
22145  m_rgRowHandles),
22146  hAccessor);
22147 
22148 if (FAILED
22149  (hr))
22150  return hr;
22151 
22152  // Flush
22153  // Users
22154  // Data
22155  HRESULT hrFlush = pT->FlushData (hRow, hAccessor);
22156 
22157 if (SUCCEEDED (hrFlush))
22158  return hr; // note:
22159  // we
22160  // could
22161  // have
22162  // DB_S_ERRORSOCCURRED
22163  // from
22164  // TransferData
22165  else
22166 
22167 return
22168  hrFlush;
22169 }
22170 
22171 
22172 STDMETHOD (InsertRow) (HCHAPTER /* hReserved
22173  */
22174  ,
22175  HACCESSOR
22176  hAccessor,
22177 
22178 void
22179  *pData,
22180  HROW
22181  *
22182  phRow)
22183 
22184  {
22185 
22186 ATLTRACE
22187  (atlTraceDBProvider,
22188  2,
22189  _T
22190  ("IRowsetChangeImpl::InsertRow\n"));
22191 
22192 
22193 T * pT =
22194  (T *) this;
22195 
22196 T::
22197  ObjectLock
22198  lock (pT);
22199 
22200 
22201 __if_exists
22202  (T::
22203  Fire_OnRowChange)
22204 
22205  {
22206 
22207 HRESULT hrNotify = S_OK; // Used
22208  // for
22209  // responses
22210  // to
22211  // notifications
22212 
22213  // Check to
22214  // see if
22215  // someone is
22216  // in an
22217  // event
22218  // handler.
22219  // If we do,
22220  // then
22221  // we should
22222  // return
22223  // DB_E_NOTREENTRANT.
22224  if (!pT->
22225  IncrementMutex
22226  ())
22227  {
22228 
22229  // Note, we
22230  // can't set
22231  // this above
22232  // because we
22233  // may
22234  // inadvertantly
22235  // step on
22236  // someone
22237  // elses
22238  // *phRow
22239  if (phRow !=
22240  NULL)
22241  *phRow = NULL;
22242 
22243 return
22244  DB_E_NOTREENTRANT;
22245 
22246 }
22247 
22248  else
22249 
22250 pT->
22251  DecrementMutex
22252  ();
22253 }
22254 
22255 
22256  // Check to
22257  // see if the
22258  // DBPROP_UPDATABILITY
22259  // value
22260  // DBPROPVAL_UP_CHANGE
22261  // is set.
22262  // If not,
22263  // then this
22264  // method
22265  // should
22266  // return
22267  // DB_E_NOTSUPPORTED.
22268  CComVariant
22269  varChange;
22270 
22271 HRESULT hr =
22272  pT->
22273  GetPropValue
22274  (&DBPROPSET_ROWSET,
22275  DBPROP_UPDATABILITY,
22276 
22277 &varChange);
22278 
22279 if (!
22280  (varChange.
22281  iVal &
22282  DBPROPVAL_UP_INSERT))
22283 
22284  return
22285  DB_E_NOTSUPPORTED;
22286 
22287 
22288 
22289 if (phRow
22290  !=
22291  NULL)
22292  *phRow = NULL;
22293 
22294 
22295  // validate
22296  // that the
22297  // hAccessor
22298  // is valid
22299  T::_BindType *
22300  pBinding;
22301 
22302 bool bFound =
22303  pT->
22304  m_rgBindings.
22305  Lookup ((INT_PTR) hAccessor, pBinding);
22306 if (!bFound || pBinding == NULL)
22307  return DB_E_BADACCESSORHANDLE;
22308 
22309  // validate
22310  // parameters
22311  if (pData ==
22312  NULL
22313  &&
22314  pBinding->
22315  cBindings
22316  !=
22317  0)
22318  return
22319  E_INVALIDARG;
22320 
22321 
22322  // Check to
22323  // see if
22324  // DBPROP_CANHOLDROWS
22325  // is set to
22326  // false. In
22327  // this
22328  // case,
22329  // return a
22330  // DB_E_ROWSNOTRELEASED
22331  // if there
22332  // are any
22333  // pending
22334  // changes.
22335  CComVariant
22336  varHoldRows;
22337 
22338 hr =
22339  pT->
22340  GetPropValue
22341  (&DBPROPSET_ROWSET,
22342  DBPROP_CANHOLDROWS,
22343 
22344 &varHoldRows);
22345 
22346 
22347 if (FAILED
22348  (hr)
22349  ||
22350  varHoldRows.
22351  boolVal
22352  ==
22354 
22355  {
22356 
22357 if (pT->
22358  m_rgRowHandles.
22359  GetCount
22360  () > 0)
22361  {
22362 
22363 RowClass *
22364  pCheckRow =
22365  NULL;
22366 
22367 POSITION pos
22368  =
22369  pT->
22370  m_rgRowHandles.
22371  GetStartPosition
22372  ();
22373 
22374 
22375 while (pos
22376  !=
22377  NULL)
22378 
22379  {
22380 
22381 MapClass::
22382  CPair *
22383  pPair =
22384  pT->
22385  m_rgRowHandles.
22386  GetNext (pos);
22387 
22388 ATLASSERT
22389  (pPair !=
22390  NULL);
22391 
22392 HROW
22393  hCheckRow =
22394  pPair->m_key;
22395 
22396 bool bFound =
22397  pT->
22398  m_rgRowHandles.
22399  Lookup
22400  (hCheckRow,
22401  pCheckRow);
22402 
22403 
22404 if (bFound
22405  &&
22406  pCheckRow
22407  != NULL
22408  &&
22409 
22410 pCheckRow->
22411  m_status
22412  !=
22413  DBPENDINGSTATUS_UNCHANGED)
22414 
22415  return
22416  DB_E_ROWSNOTRELEASED;
22417 
22418 }
22419 
22420 }
22421 
22422 }
22423 
22424 
22425  // We should
22426  // check
22427  // DBPROP_IMMOBILEROWS
22428  // and then
22429  // call an
22430  // ordering
22431  // routine in
22432  // the user's
22433  // code.
22434  // Create a
22435  // row and
22436  // place into
22437  // m_rgRowData
22438  Storage newRow; // Create
22439  // an
22440  // instance
22441  // of
22442  // the
22443  // users
22444  // data
22445  CComVariant
22446  var;
22447 
22448 HRESULT
22449  hrProps =
22450  pT->
22451  GetPropValue
22452  (&DBPROPSET_ROWSET,
22453 
22454 DBPROP_BOOKMARKS,
22455  &var);
22456 
22457 if (SUCCEEDED
22458  (hrProps)
22459  && var.
22460  boolVal
22461  !=
22463 
22464  {
22465 
22466 DBORDINAL
22467  cCols;
22468 
22469 ATLCOLUMNINFO
22470  * pInfo =
22471  T::
22472  GetColumnInfo
22473  (pT, &cCols);
22474 
22475 ATLASSERT
22476  (pInfo !=
22477  NULL);
22478 
22479 for
22480  (DBORDINAL i =
22481  0; i < cCols;
22482  i++)
22483  {
22484 
22485 if (pInfo[i].
22486  iOrdinal
22487  == 0)
22488  {
22489 
22490 switch (pInfo
22491  [i].
22492  wType)
22493 
22494  {
22495 
22496 case DBTYPE_BYTES:
22497 
22498 *((DBBKMARK *) (&newRow + pInfo[i].cbOffset)) = (ULONG_PTR) (pT->m_rgRowData.GetCount () + 1);
22499 break;
22500 default:
22501 
22502 ATLASSERT
22503  (FALSE);
22504 };
22505 
22506 }
22507 
22508 }
22509 
22510 }
22511 
22512 
22513  // Call
22514  // CreateRow
22515  // to make a
22516  // new hRow
22517  HROW
22518  hInsertedRow =
22519  NULL;
22520 
22521 DBCOUNTITEM
22522  ulRowsObtained
22523  = 0;
22524 
22525 
22526 size_t lSize
22527  =
22528  pT->
22529  m_rgRowData.
22530  GetCount ();
22531 
22532 
22533 hr =
22534  pT->
22535  CreateRow ((LONG_PTR) lSize, ulRowsObtained, &hInsertedRow);
22536 
22537 if (FAILED (hr))
22538  {
22539 
22540 return hr;
22541 }
22542 
22543  else
22544 
22545  {
22546 
22547 __if_exists
22548  (T::
22549  Fire_OnRowChange)
22550 
22551  {
22552 
22553 hrNotify =
22554  pT->
22555  Fire_OnRowChange
22556  (pT, 1,
22557  &hInsertedRow,
22558  DBREASON_ROW_INSERT,
22559 
22560 DBEVENTPHASE_OKTODO,
22561  FALSE);
22562 
22563 if ((hrNotify
22564  != S_OK)
22565  &&
22566  (hrNotify
22567  !=
22568  E_FAIL))
22569 
22570  {
22571 
22572 pT->
22573  m_rgRowHandles.
22574  RemoveKey ((RowClass::KeyType) hInsertedRow);
22575 return DB_E_CANCELED;
22576 }
22577 
22578 
22579 hrNotify =
22580  pT->
22581  Fire_OnRowChange
22582  (pT, 1,
22583  &hInsertedRow,
22584  DBREASON_ROW_INSERT,
22585 
22586 DBEVENTPHASE_ABOUTTODO,
22587  FALSE);
22588 
22589 if ((hrNotify
22590  != S_OK)
22591  &&
22592  (hrNotify
22593  !=
22594  E_FAIL))
22595 
22596  {
22597 
22598 pT->
22599  m_rgRowHandles.
22600  RemoveKey ((RowClass::KeyType) hInsertedRow);
22601 return DB_E_CANCELED;
22602 }
22603 
22604 }
22605 
22606 }
22607 
22608 
22609  // Add in the
22610  // storage
22611  // and
22612  // linkeage
22613  // for the
22614  // row
22615  CComVariant
22616  varOrderedInsert;
22617 
22618 
22619  // Need to
22620  // determine
22621  // if we want
22622  // ordered
22623  // insertions
22624  bool
22625  bOrderedInsert;
22626 
22627 hr =
22628  pT->
22629  GetPropValue
22630  (&DBPROPSET_ROWSET,
22631  DBPROP_IMMOBILEROWS,
22632 
22633 &varOrderedInsert);
22634 
22635 (FAILED (hr)
22636  ||
22637  varOrderedInsert.
22638  boolVal !=
22640  ?
22641 
22642 bOrderedInsert
22643  =
22644  false :
22645  bOrderedInsert
22646  = true;
22647 
22648  // if
22649  // (!pT->m_rgRowData.Add(newRow))
22650  // {
22651  // ATLTRACE(atlTraceDBProvider,
22652  // 0,
22653  // _T("Failed
22654  // to add
22655  // record Out
22656  // of
22657  // Memory"));
22658  // return
22659  // E_OUTOFMEMORY;
22660  // }
22661  _ATLTRY
22662  {
22663 
22664 pT->
22665  m_rgRowData.
22666  Add (newRow);
22667 
22668 }
22669 
22670 _ATLCATCH (e)
22671 
22672  {
22673 
22674 _ATLDELETEEXCEPTION
22675  (e);
22676 
22677 ATLTRACE
22678  (atlTraceDBProvider,
22679  0,
22680  _T
22681  ("Failed to add record Out of Memory"));
22682 
22683 return
22684  E_OUTOFMEMORY;
22685 
22686 }
22687 
22688 
22689  // Set the
22690  // inserted
22691  // row's
22692  // status to
22693  // DBPENDINGSTATUS_NEW
22694  // if it is
22695  // deferred.
22696  // This will
22697  // prevent a
22698  // spurious
22699  // Notification
22700  // for
22701  // ROW_FIRSTCHANGE
22702  // from
22703  // firing in
22704  // IRowsetUpdateImpl::SetData.
22705  CComVariant
22706  varDeferred;
22707 
22708 bool
22709  bDeferred;
22710 
22711 HRESULT
22712  hrDeferred =
22713  pT->
22714  GetPropValue
22715  (&DBPROPSET_ROWSET,
22716  DBPROP_IRowsetUpdate,
22717 
22718 &varDeferred);
22719 
22720 (FAILED
22721  (hrDeferred)
22722  ||
22723  varDeferred.
22724  boolVal ==
22726  ? bDeferred =
22727  false :
22728  bDeferred =
22729  true;
22730 
22731 
22732 RowClass *
22733  pRow;
22734 
22735 ATLVERIFY
22736  (pT->
22737  m_rgRowHandles.
22738  Lookup
22739  (hInsertedRow,
22740  pRow));
22741 
22742 ATLASSERT
22743  (pRow !=
22744  NULL);
22745 
22746  // Set the
22747  // status to
22748  // NEW +
22749  // UNCHANGED
22750  // so we
22751  // don't
22752  // generate
22753  // COLUMN_SET
22754  // or
22755  // FIRSTCHANGE
22756  // events in
22757  // SetData.
22758  // We'll
22759  // switch it
22760  // back to
22761  // zero after
22762  // the
22763  // operation.
22764  pRow->
22765  m_status =
22766  DBPENDINGSTATUS_NEW
22767  |
22768  DBPENDINGSTATUS_UNCHANGED;
22769 
22770 
22771  // Call
22772  // SetData,
22773  // if
22774  // necessary
22775  if (pData !=
22776  NULL)
22777  {
22778 
22779 hr =
22780  SetData
22781  (hInsertedRow,
22782  hAccessor,
22783  pData);
22784 
22785 if (FAILED
22786  (hr))
22787  {
22788 
22789 __if_exists
22790  (T::
22791  Fire_OnRowChange)
22792 
22793  {
22794 
22795 pT->
22796  Fire_OnRowChange
22797  (pT, 1,
22798  &hInsertedRow,
22799  DBREASON_ROW_INSERT,
22800 
22801 DBEVENTPHASE_FAILEDTODO,
22802  TRUE);
22803 }
22804 
22805 }
22806 
22807 }
22808 
22809 
22810 if
22811  (!bDeferred)
22812  pRow->
22813  m_status = 0;
22814 
22815  else
22816 
22817 pRow->
22818  m_status =
22819  DBPENDINGSTATUS_NEW;
22820 
22821 
22822 __if_exists
22823  (T::
22824  Fire_OnRowChange)
22825 
22826  {
22827 
22828 hrNotify =
22829  pT->
22830  Fire_OnRowChange
22831  (pT, 1,
22832  &hInsertedRow,
22833  DBREASON_ROW_INSERT,
22834 
22835 DBEVENTPHASE_SYNCHAFTER,
22836  FALSE);
22837 
22838 if ((hrNotify
22839  != S_OK)
22840  &&
22841  (hrNotify
22842  !=
22843  E_FAIL))
22844 
22845  {
22846 
22847  // Remove
22848  // storage
22849  RowClass *
22850  pRow;
22851 
22852 ATLVERIFY
22853  (pT->
22854  m_rgRowHandles.
22855  Lookup
22856  (hInsertedRow,
22857  pRow));
22858 
22859 ATLASSERT
22860  (pRow !=
22861  NULL);
22862 
22863 pT->
22864  m_rgRowData.
22865  RemoveAt
22866  (pRow->
22867  m_iRowset);
22868 
22869 
22870  // Remove
22871  // Handle
22872  pT->
22873  m_rgRowHandles.
22874  RemoveKey ((RowClass::KeyType) hInsertedRow);
22875 
22876 return DB_E_CANCELED;
22877 }
22878 
22879 
22880 pT->
22881  Fire_OnRowChange
22882  (pT, 1,
22883  &hInsertedRow,
22884  DBREASON_ROW_INSERT,
22885 
22886 DBEVENTPHASE_DIDEVENT,
22887  TRUE);
22888 }
22889 
22890 
22891 if (phRow !=
22892  NULL
22893  &&
22894  SUCCEEDED
22895  (hr))
22896  *phRow =
22897  hInsertedRow;
22898 
22899 
22900 return hr;
22901 
22902 }
22903 
22904 
22905 
22906  // Callbacks
22907  // to
22908  // Provider
22909  HRESULT
22910  FlushData
22911  (HROW,
22912  HACCESSOR)
22913  {
22914 
22915  // The
22916  // provider
22917  // overrides
22918  // this
22919  // function
22920  // to commit
22921  // data to
22922  // its store
22923  return S_OK;
22924 }
22925 
22926 };
22927 
22928 
22929 
22930 // IRowsetImpl
22931 template < class T, class RowsetInterface,
22932 class RowClass = CSimpleRow,
22933 class MapClass = CAtlMap < RowClass::KeyType, RowClass * >>
22934 class ATL_NO_VTABLE IRowsetImpl:public
22935  RowsetInterface
22936 
22937  {
22938 
22939 public:
22940 typedef
22941  RowClass
22943 
22945  ()
22946  {
22947 
22948 m_iRowset =
22949  0;
22950 
22951 m_bCanScrollBack
22952  = false;
22953 
22954 m_bCanFetchBack
22955  = false;
22956 
22957 m_bRemoveDeleted
22958  = true;
22959 
22960 m_bIRowsetUpdate
22961  = false;
22962 
22963 m_bReset =
22964  true;
22965 
22966 m_bExternalFetch
22967  = false;
22968 }
22969 
22970 ~IRowsetImpl
22971  ()
22972  {
22973 
22974  // for (int i
22975  // = 0; i <
22976  // m_rgRowHandles.GetCount();
22977  // i++)
22978  // delete
22979  // (m_rgRowHandles.GetValueAt(i));
22980  POSITION pos =
22981  m_rgRowHandles.
22982  GetStartPosition
22983  ();
22984 
22985 while (pos !=
22986  NULL)
22987 
22988  {
22989 
22990 MapClass::
22991  CPair *
22992  pPair =
22993  m_rgRowHandles.
22994  GetNext (pos);
22995 
22996 ATLASSERT
22997  (pPair !=
22998  NULL);
22999 
23000 delete
23001  pPair->
23002  m_value;
23003 }
23004 
23005 }
23006 
23007 HRESULT
23008  RefRows
23009  (DBCOUNTITEM
23010  cRows,
23011  const HROW
23012  rghRows[],
23013  DBREFCOUNT
23014  rgRefCounts
23015  [],
23016 
23017 DBROWSTATUS
23018  rgRowStatus
23019  [],
23020  BOOL bAdd)
23021  {
23022 
23023 ATLTRACE
23024  (atlTraceDBProvider,
23025  2,
23026  _T
23027  ("IRowsetImpl::AddRefRows\n"));
23028 
23029 if (cRows ==
23030  0)
23031  return S_OK;
23032 
23033 if (rghRows
23034  ==
23035  NULL)
23036  return
23037  E_INVALIDARG;
23038 
23039 T::
23040  ObjectLock
23041  cab ((T *)
23042  this);
23043 
23044 BOOL
23045  bSuccess1 =
23046  FALSE;
23047 
23048 BOOL bFailed1
23049  = FALSE;
23050 
23051 DBROWSTATUS
23052  rs;
23053 
23054 DWORD dwRef;
23055 
23056 
23057 __if_exists
23058  (T::
23059  Fire_OnRowChange)
23060 
23061  {
23062 
23063  // Maintain
23064  // an array
23065  // of handles
23066  // w/ zero
23067  // ref counts
23068  // for
23069  // notification
23070  CAtlArray <
23071  HROW >
23072  arrZeroHandles;
23073 
23074 }
23075 
23076 
23077 for (ULONG
23078  iRow =
23079  0;
23080  iRow <
23081  cRows;
23082  iRow++)
23083 
23084  {
23085 
23086 HROW hRowCur
23087  =
23088  rghRows[iRow];
23089 
23090 RowClass *
23091  pRow;
23092 
23093 bool bFound =
23094  m_rgRowHandles.
23095  Lookup ((RowClass::KeyType) hRowCur, pRow);
23096 if (!bFound || pRow == NULL)
23097  {
23098 
23099 ATLTRACE
23100  (atlTraceDBProvider,
23101  0,
23102  _T
23103  ("Could not find HANDLE %x in list\n"));
23104 
23105 rs =
23106  DBROWSTATUS_E_INVALID;
23107 
23108 dwRef = 0;
23109 
23110 bFailed1 =
23111  TRUE;
23112 }
23113 
23114  else
23115 
23116  {
23117 
23118 
23119 if (pRow->
23120  m_status
23121  !=
23122  DBPENDINGSTATUS_UNCHANGED
23123  &&
23124 
23125 pRow->
23126  m_status
23127  !=
23128  DBPENDINGSTATUS_INVALIDROW
23129  &&
23130 
23131 pRow->
23132  m_dwRef
23133  == 0
23134  &&
23135  !bAdd)
23136  {
23137 
23138 if
23139  (rgRefCounts)
23140 
23141  rgRefCounts
23142  [iRow] = 0;
23143 
23144 if
23145  (rgRowStatus
23146  !=
23147  NULL)
23148  rgRowStatus
23149  [iRow] =
23150  DBROWSTATUS_E_INVALID;
23151 
23152 bFailed1 =
23153  TRUE;
23154 
23155 continue;
23156 }
23157 
23158 
23159  // Check if
23160  // we're in
23161  // immediate
23162  // or
23163  // deferred
23164  // mode
23165  CComVariant
23166  varDeferred;
23167 
23168 bool
23169  bDeferred;
23170 
23171 T * pT =
23172  (T *) this;
23173 
23174 HRESULT hr =
23175  pT->
23176  GetPropValue
23177  (&DBPROPSET_ROWSET,
23178 
23179 DBPROP_IRowsetUpdate,
23180  &varDeferred);
23181 
23182 (FAILED (hr)
23183  ||
23184  varDeferred.
23185  boolVal ==
23187  ?
23188 bDeferred =
23189  false :
23190  bDeferred =
23191  true;
23192 
23193 
23194 if
23195  (!bDeferred
23196  && bAdd
23197  &&
23198 pRow->
23199  m_status ==
23200  DBPENDINGSTATUS_DELETED)
23201 
23202  {
23203 
23204 bFailed1 =
23205  TRUE;
23206 
23207 if
23208  (rgRowStatus
23209  !=
23210  NULL)
23211  rgRowStatus
23212  [iRow] =
23213  DBROWSTATUS_E_DELETED;
23214 
23215 continue;
23216 }
23217 
23218 
23219 if (bAdd)
23220  dwRef =
23221  pRow->
23222  AddRefRow ();
23223 
23224  else
23225 
23226  {
23227 
23228 dwRef =
23229  pRow->
23230  ReleaseRow ();
23231 
23232 if ((pRow->
23233  m_status
23234  !=
23235  DBPENDINGSTATUS_UNCHANGED
23236  &&
23237 
23238 pRow->
23239  m_status
23240  != 0
23241  &&
23242 
23243 pRow->
23244  m_status
23245  !=
23246  DBPENDINGSTATUS_INVALIDROW)
23247  &&
23248 
23249 bDeferred)
23250 
23251  {
23252 
23253 if
23254  (rgRefCounts)
23255 
23256  rgRefCounts
23257  [iRow] =
23258  dwRef;
23259 
23260 if
23261  (rgRowStatus
23262  !=
23263  NULL)
23264  rgRowStatus
23265  [iRow] =
23266  DBROWSTATUS_S_PENDINGCHANGES;
23267 
23268 bSuccess1 =
23269  TRUE;
23270 
23271 continue;
23272 }
23273 
23274 
23275 if (dwRef ==
23276  0)
23277  {
23278 
23279 __if_exists
23280  (T::
23281  Fire_OnRowsetChange)
23282 
23283  {
23284 
23285 _ATLTRY
23286  {
23287 
23288 arrZeroHandles.
23289  Add (hRowCur);
23290 
23291 }
23292 
23293 _ATLCATCH (e)
23294 
23295  {
23296 
23297 _ATLDELETEEXCEPTION
23298  (e);
23299 
23300 return
23301  E_FAIL;
23302 }
23303 
23304 }
23305 
23306 
23307  // Now
23308  // determine
23309  // if the
23310  // DBPROP_REMOVEDELETED
23311  // property
23312  // is
23313  // ATL_VARIANT_FALSE.
23314  // If so,
23315  // then do
23316  // NOT remove
23317  // the
23318  // row.
23319  hr =
23320  pT->
23321  GetPropValue
23322  (&DBPROPSET_ROWSET,
23323 
23324 DBPROP_REMOVEDELETED,
23325  &varDeferred);
23326 
23327 if (FAILED
23328  (hr)
23329  ||
23330  varDeferred.
23331  boolVal
23332  !=
23334 
23335  {
23336 
23337 delete pRow;
23338 
23339 m_rgRowHandles.
23340  RemoveKey ((RowClass::KeyType) hRowCur);
23341 }
23342 
23343 }
23344 
23345 }
23346 
23347 bSuccess1 =
23348  TRUE;
23349 
23350 rs =
23351  DBROWSTATUS_S_OK;
23352 
23353 }
23354 
23355 if
23356  (rgRefCounts)
23357 
23358  rgRefCounts
23359  [iRow] =
23360  dwRef;
23361 
23362 if
23363  (rgRowStatus
23364  !=
23365  NULL)
23366  rgRowStatus
23367  [iRow] = rs;
23368 
23369 }
23370 
23371 
23372 __if_exists
23373  (T::
23374  Fire_OnRowsetChange)
23375 
23376  {
23377 
23378 if (!bAdd
23379  &&
23380  arrZeroHandles.
23381  GetCount
23382  () > 0)
23383  {
23384 
23385 T * pT =
23386  (T *) this;
23387 
23388 pT->
23389  Fire_OnRowChange
23390  (pT,
23391  (ULONG_PTR)
23392  arrZeroHandles.
23393  GetCount (),
23394  arrZeroHandles.
23395  GetData (),
23396 
23397 DBREASON_ROW_RELEASE,
23398  DBEVENTPHASE_DIDEVENT,
23399  FALSE);
23400 }
23401 
23402 }
23403 
23404 
23405 if
23406  (!bSuccess1
23407  && !bFailed1)
23408 
23409  {
23410 
23411 ATLTRACE
23412  (atlTraceDBProvider,
23413  0,
23414  _T
23415  ("IRowsetImpl::RefRows Unexpected state\n"));
23416 
23417 return
23418  E_FAIL;
23419 }
23420 
23421 HRESULT hr =
23422  S_OK;
23423 
23424 if (bSuccess1
23425  &&
23426  bFailed1)
23427 
23428  hr =
23429  DB_S_ERRORSOCCURRED;
23430 
23431 if
23432  (!bSuccess1
23433  && bFailed1)
23434 
23435  hr =
23436  DB_E_ERRORSOCCURRED;
23437 
23438 return hr;
23439 }
23440 
23441 
23442 STDMETHOD
23443  (AddRefRows)
23444  (DBCOUNTITEM
23445  cRows,
23446 
23447 const HROW
23448  rghRows[],
23449 
23450 DBREFCOUNT
23451  rgRefCounts
23452  [],
23453 
23454 DBROWSTATUS
23455  rgRowStatus
23456  [])
23457  {
23458 
23459 ATLTRACE
23460  (atlTraceDBProvider,
23461  2,
23462  _T
23463  ("IRowsetImpl::AddRefRows\n"));
23464 
23465 if (cRows ==
23466  0)
23467  return S_OK;
23468 
23469 return
23470  RefRows
23471  (cRows,
23472  rghRows,
23473  rgRefCounts,
23474  rgRowStatus,
23475  TRUE);
23476 }
23477 
23478 virtual
23479  DBSTATUS
23480  GetDBStatus
23481  (RowClass *,
23482  ATLCOLUMNINFO
23483  *)
23484  {
23485 
23486 return
23487  DBSTATUS_S_OK;
23488 
23489 }
23490 
23491 virtual
23492  HRESULT
23493  SetDBStatus
23494  (DBSTATUS *,
23495  RowClass *,
23496  ATLCOLUMNINFO
23497  *)
23498  {
23499 
23500  // The
23501  // provider
23502  // overrides
23503  // this
23504  // function
23505  // to handle
23506  // special
23507  // processing
23508  // for
23509  // DBSTATUS_S_ISNULL
23510  // and
23511  // DBSTATUS_S_DEFAULT.
23512  //
23513  return S_OK;
23514 }
23515 
23516 
23518  HRESULT
23519  GetDataHelper
23520  (HACCESSOR
23521  hAccessor,
23522 
23523 ATLCOLUMNINFO
23524  * &rpInfo,
23525 
23526 void
23527  **ppBinding,
23528 
23529 void
23530  *&rpSrcData,
23531 
23532 DBORDINAL &
23533  rcCols,
23534 
23535 CComPtr <
23536  IDataConvert
23537  >
23538  &rspConvert,
23539 
23540 RowClass *
23541  pRow)
23542  {
23543 
23544 ATLASSERT
23545  (ppBinding !=
23546  NULL);
23547 
23548 T * pT =
23549  (T *) this;
23550 // *ppBinding = (void*)pT->m_rgBindings.Lookup((INT_PTR)hAccessor);
23551  T::
23552  _BindingVector::
23553  CPair *
23554  pPair =
23555  pT->
23556  m_rgBindings.
23557  Lookup
23558  (hAccessor);
23559 
23560 if (pPair ==
23561  NULL
23562  ||
23563  pPair->
23564  m_value
23565  ==
23566  NULL)
23567  return
23568  DB_E_BADACCESSORHANDLE;
23569 
23570 *ppBinding =
23571  pPair->
23572  m_value;
23573 
23574 rpSrcData =
23575  (void *)
23576  &(pT->
23577  m_rgRowData
23578  [pRow->
23579  m_iRowset]);
23580 
23581 rpInfo =
23582  T::
23583  GetColumnInfo
23584  ((T *) this,
23585  &rcCols);
23586 
23587 rspConvert =
23588  pT->
23589  m_spConvert;
23590 
23591 return S_OK;
23592 
23593 
23594 }
23595 
23596 STDMETHOD
23597  (GetData)
23598  (HROW hRow,
23599 
23600 HACCESSOR
23601  hAccessor,
23602 
23603 void
23604  *pDstData)
23605  {
23606 
23607 T * pT =
23608  (T *) this;
23609 
23610 RowClass *
23611  pRow;
23612 
23613 if (hRow ==
23614  NULL)
23615  return
23616  DB_E_BADROWHANDLE;
23617 
23618 
23619 if (!pT->
23620  m_rgRowHandles.
23621  Lookup ((INT_PTR) hRow, pRow))
23622  return DB_E_BADROWHANDLE;
23623 
23624 if (pRow == NULL)
23625  return DB_E_BADROWHANDLE;
23626 
23627 return TransferData < T, RowClass, MapClass >
23628 (pT, true, pDstData, pRow, &(pT->m_rgRowHandles), hAccessor);
23629 }
23630 
23631 
23632 HRESULT
23633  CreateRow
23634  (DBROWOFFSET
23635  lRowsOffset,
23636  DBCOUNTITEM &
23637  cRowsObtained,
23638  HROW *
23639  rgRows)
23640  {
23641 
23642 RowClass *
23643  pRow = NULL;
23644 
23645 ATLASSERT
23646  (lRowsOffset
23647  >= 0);
23648 
23649 RowClass::
23650  KeyType key =
23651  lRowsOffset +
23652  1;
23653 
23654 ATLASSERT
23655  (key > 0);
23656 
23657 bool bFound =
23658  m_rgRowHandles.
23659  Lookup (key,
23660  pRow);
23661 
23662 if (!bFound
23663  || pRow
23664  ==
23665  NULL)
23666  {
23667 
23668 ATLTRY (pRow
23669  =
23670  new
23671  RowClass
23672  (lRowsOffset))
23673 
23674  if (pRow ==
23675  NULL)
23676  return
23677  E_OUTOFMEMORY;
23678 
23679 _ATLTRY
23680  {
23681 
23682 m_rgRowHandles.
23683  SetAt (key,
23684  pRow);
23685 
23686 }
23687 
23688 _ATLCATCH (e)
23689 
23690  {
23691 
23692 _ATLDELETEEXCEPTION
23693  (e);
23694 
23695 delete pRow;
23696 
23697 pRow = NULL;
23698 
23699 return
23700  E_OUTOFMEMORY;
23701 
23702 }
23703 
23704 }
23705 
23706 pRow->
23707  AddRefRow ();
23708 
23709 m_bReset =
23710  false;
23711 
23712 rgRows
23713  [cRowsObtained++]
23714  = (HROW) key;
23715 
23716 return S_OK;
23717 
23718 }
23719 
23720 
23721 HRESULT GetNextRowsSkipDeleted (HCHAPTER /* hReserved
23722  */
23723  ,
23724 
23725 DBROWOFFSET
23726  lRowsOffset,
23727 
23728 DBROWCOUNT
23729  cRows,
23730 
23731 DBCOUNTITEM
23732  *
23733  pcRowsObtained,
23734 
23735 HROW
23736  **
23737  prghRows)
23738 
23739  {
23740 
23741 ATLTRACE
23742  (atlTraceDBProvider,
23743  2,
23744  _T
23745  ("IRowsetImpl::GetNextRows\n"));
23746 
23747 T * pT =
23748  (T *) this;
23749 
23750 
23751 __if_exists
23752  (T::
23753  Fire_OnRowChange)
23754 
23755  {
23756 
23757  // Check to
23758  // see if
23759  // someone is
23760  // in an
23761  // event
23762  // handler.
23763  // If we do,
23764  // then
23765  // we should
23766  // return
23767  // DB_E_NOTREENTRANT.
23768  if (!pT->
23769  IncrementMutex
23770  ())
23771  {
23772 
23773  // Note, we
23774  // can't set
23775  // this above
23776  // this block
23777  // because we
23778  // may
23779  // inadvertantly
23780  // reset
23781  // somebody
23782  // else's
23783  // pcRowsObtained
23784  if
23785  (pcRowsObtained
23786  !=
23787  NULL)
23788  *pcRowsObtained
23789  = 0;
23790 
23791 return
23792  DB_E_NOTREENTRANT;
23793 
23794 }
23795 
23796  else
23797 
23798 pT->
23799  DecrementMutex
23800  ();
23801 }
23802 
23803 
23804 if
23805  (pcRowsObtained
23806  !=
23807  NULL)
23808  *pcRowsObtained
23809  = 0;
23810 
23811 if (prghRows
23812  == NULL
23813  ||
23814  pcRowsObtained
23815  ==
23816  NULL)
23817  return
23818  E_INVALIDARG;
23819 
23820 if (cRows ==
23821  0)
23822  return S_OK;
23823 
23824 HRESULT hr =
23825  S_OK;
23826 
23827 T::
23828  ObjectLock
23829  cab (pT);
23830 
23831 if
23832  (lRowsOffset <
23833  0
23834  &&
23835  !m_bCanScrollBack)
23836 
23837  return
23838  DB_E_CANTSCROLLBACKWARDS;
23839 
23840 if (cRows < 0
23841  &&
23842  !m_bCanFetchBack)
23843 
23844  return
23845  DB_E_CANTFETCHBACKWARDS;
23846 
23847 
23848 DBROWOFFSET
23849  cRowsInSet =
23850  (DBROWOFFSET)
23851  pT->
23852  m_rgRowData.
23853  GetCount ();
23854 
23855 
23856 DBROWOFFSET
23857  iStepSize =
23858  cRows >=
23859  0 ? 1 : -1;
23860  // If cRows
23861  // ==
23862  // MINLONG_PTR,
23863  // we can't
23864  // use ABS on
23865  // it.
23866  // Therefore,
23867  // we reset
23868  // it
23869  // to a value
23870  // just
23871  // greater
23872  // than
23873  // cRowsInSet
23874  if (cRows == MINLONG_PTR && cRowsInSet != MINLONG_PTR)
23875  cRows = cRowsInSet + 2; // set
23876  // the
23877  // value
23878  // to
23879  // something
23880  // we
23881  // can
23882  // deal
23883  // with
23884  else
23885 
23886 cRows =
23887  AbsVal
23888  (cRows);
23889 
23890  // First,
23891  // simulate
23892  // the
23893  // operation,
23894  // skipping
23895  // over any
23896  // deleted
23897  // rows,
23898  // calculate
23899  // the number
23900  // of rows
23901  // retrieved,
23902  // and return
23903  // an error
23904  // code if
23905  // appropriate
23906 
23907 DBROWOFFSET
23908  nCurrentRow =
23909  m_iRowset;
23910 
23911  // Note, if
23912  // m_bReset,
23913  // m_iRowset
23914  // must be 0
23915  if (m_bReset
23916  &&
23917  (lRowsOffset
23918  < 0
23919  ||
23920  (lRowsOffset
23921  == 0
23922  &&
23923  iStepSize
23924  <
23925  0)))
23926  nCurrentRow =
23927  cRowsInSet;
23928 
23929  // skip the
23930  // rows
23931  // according
23932  // to the
23933  // lRowsOffset
23934  // value
23935  if
23936  (lRowsOffset >
23937  0)
23938  {
23939 
23940 DBROWOFFSET
23941  nRowsToSkip =
23942  lRowsOffset;
23943 
23944 
23945 while
23946  (nRowsToSkip >
23947  0
23948  &&
23949  nCurrentRow
23950  <=
23951  cRowsInSet)
23952  {
23953 
23954 RowClass *
23955  pRow = NULL;
23956 
23957 RowClass::
23958  KeyType key =
23959  nCurrentRow +
23960  1;
23961 
23962 bool bFound =
23963  m_rgRowHandles.
23964  Lookup (key,
23965  pRow);
23966 
23967 if (bFound
23968  && pRow
23969  !=
23970  NULL)
23971  {
23972 
23973 if (pRow->
23974  m_status
23975  ==
23976  DBPENDINGSTATUS_DELETED)
23977 
23978  {
23979 
23980 nCurrentRow++;
23981 
23982 continue;
23983 }
23984 
23985 }
23986 
23987 nCurrentRow++;
23988 
23989 nRowsToSkip--;
23990 
23991 }
23992 
23993 
23994 if
23995  (nCurrentRow >
23996  cRowsInSet)
23997  return
23998  DB_S_ENDOFROWSET;
23999 
24000 }
24001 
24002  else
24003  if
24004  (lRowsOffset <
24005  0)
24006  {
24007 
24008 DBROWOFFSET nRowsToSkip = lRowsOffset;
24009 if (nRowsToSkip == MINLONG_PTR && cRowsInSet != MINLONG_PTR)
24010  nRowsToSkip = cRowsInSet + 2; // set
24011  // the
24012  // value
24013  // to
24014  // something
24015  // we
24016  // can
24017  // deal
24018  // with
24019  else
24020 
24021 nRowsToSkip =
24022  -nRowsToSkip;
24023 
24024 
24025 while
24026  (nRowsToSkip >
24027  0
24028  &&
24029  nCurrentRow >
24030  0)
24031  {
24032 
24033 nCurrentRow--;
24034 
24035 
24036 RowClass *
24037  pRow = NULL;
24038 
24039 RowClass::
24040  KeyType key =
24041  nCurrentRow +
24042  1;
24043 
24044 bool bFound =
24045  m_rgRowHandles.
24046  Lookup (key,
24047  pRow);
24048 
24049 if (bFound
24050  && pRow
24051  !=
24052  NULL)
24053  {
24054 
24055 if (pRow->
24056  m_status
24057  ==
24058  DBPENDINGSTATUS_DELETED)
24059 
24060  {
24061 
24062 continue;
24063 }
24064 
24065 }
24066 
24067 nRowsToSkip--;
24068 }
24069 
24070 
24071 if
24072  (nCurrentRow <
24073  0)
24074  return
24075  DB_S_ENDOFROWSET;
24076 
24077 }
24078 
24079 
24080 DBROWOFFSET
24081  nFetchStartPosition
24082  = nCurrentRow;
24083 
24084 
24085  // now fetch
24086  // the rows
24087  DBROWOFFSET
24088  cRowsToFetch =
24089  cRows;
24090 
24091 DBROWOFFSET
24092  cRowsFetched =
24093  0;
24094 
24095 if (iStepSize
24096  == 1)
24097  {
24098 
24099 while
24100  (cRowsToFetch
24101  > 0
24102  &&
24103  nCurrentRow <
24104  cRowsInSet)
24105  {
24106 
24107 RowClass *
24108  pRow = NULL;
24109 
24110 RowClass::
24111  KeyType key =
24112  nCurrentRow +
24113  1;
24114 
24115 bool bFound =
24116  m_rgRowHandles.
24117  Lookup (key,
24118  pRow);
24119 
24120 if (bFound
24121  && pRow
24122  !=
24123  NULL)
24124  {
24125 
24126 if (pRow->
24127  m_status
24128  ==
24129  DBPENDINGSTATUS_DELETED)
24130 
24131  {
24132 
24133 nCurrentRow++;
24134 
24135 continue;
24136 }
24137 
24138 }
24139 
24140  // now we
24141  // would
24142  // fetch the
24143  // row
24144  cRowsFetched++;
24145 
24146 cRowsToFetch--;
24147 
24148 nCurrentRow++;
24149 
24150 }
24151 
24152 }
24153 
24154  else
24155 
24156  {
24157 
24158 while
24159  (cRowsToFetch
24160  > 0
24161  &&
24162  nCurrentRow >
24163  0)
24164  {
24165 
24166 nCurrentRow--;
24167 
24168 RowClass *
24169  pRow = NULL;
24170 
24171 RowClass::
24172  KeyType key =
24173  nCurrentRow +
24174  1;
24175 
24176 bool bFound =
24177  m_rgRowHandles.
24178  Lookup (key,
24179  pRow);
24180 
24181 if (bFound
24182  && pRow
24183  !=
24184  NULL)
24185  {
24186 
24187 if (pRow->
24188  m_status
24189  ==
24190  DBPENDINGSTATUS_DELETED)
24191 
24192  {
24193 
24194 continue;
24195 }
24196 
24197 }
24198 
24199  // now we
24200  // would
24201  // fetch the
24202  // row
24203  cRowsFetched++;
24204 
24205 cRowsToFetch--;
24206 
24207 }
24208 
24209 }
24210 
24211 
24212  // we could
24213  // not fetch
24214  // any rows
24215  if
24216  (cRowsFetched
24217  ==
24218  0)
24219  return
24220  DB_S_ENDOFROWSET;
24221 
24222 
24223  // Simulation
24224  // completed...
24225  // no
24226  // problems
24227  // detected...
24228  // we can now
24229  // perform
24230  // the real
24231  // fetching
24232 
24233  // Fire
24234  // events for
24235  // OKTODO and
24236  // ABOUTTODO
24237  // after all
24238  // validation
24239  // has taken
24240  // place but
24241  // before any
24242  // permanent
24243  // changes to
24244  // the rowset
24245  // state take
24246  // place
24247  __if_exists
24248  (T::
24249  Fire_OnRowsetChange)
24250 
24251  {
24252 
24253  // Only fire
24254  // these
24255  // events if
24256  // we're not
24257  // being
24258  // called by
24259  // a
24260  // bookmark
24261  // operation
24262  // (which is
24263  // why
24264  // m_bExternalFetch
24265  // would be
24266  // set to
24267  // true)
24268  if
24269  (!m_bExternalFetch)
24270 
24271  {
24272 
24273 HRESULT
24274  hrNotify =
24275  pT->
24276  Fire_OnRowsetChange
24277  (pT,
24278 
24279 DBREASON_ROWSET_FETCHPOSITIONCHANGE,
24280  DBEVENTPHASE_OKTODO,
24281  FALSE);
24282 
24283 if (hrNotify
24284  ==
24285  S_FALSE)
24286 
24287  return
24288  DB_E_CANCELED;
24289 
24290  else
24291 
24292  {
24293 
24294 hrNotify =
24295  pT->
24296  Fire_OnRowsetChange
24297  (pT,
24298  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
24299 
24300 DBEVENTPHASE_ABOUTTODO,
24301  FALSE);
24302 
24303 if (hrNotify
24304  ==
24305  S_FALSE)
24306 
24307  return
24308  DB_E_CANCELED;
24309 
24310  else
24311 
24312  {
24313 
24314 hrNotify =
24315  pT->
24316  Fire_OnRowsetChange
24317  (pT,
24318  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
24319 
24320 DBEVENTPHASE_SYNCHAFTER,
24321  FALSE);
24322 
24323 if (hrNotify
24324  ==
24325  S_FALSE)
24326 
24327  return
24328  DB_E_CANCELED;
24329 
24330 }
24331 
24332 }
24333 
24334 }
24335 
24336 }
24337 
24338 
24339 nCurrentRow = nFetchStartPosition; // we
24340  // already
24341  // calculated
24342  // the
24343  // 'start
24344  // fetch
24345  // position'
24346  // in
24347  // the
24348  // simulation
24349  // stage
24350  ATLASSERT
24351  (nCurrentRow
24352  >= 0
24353  &&
24354  nCurrentRow
24355  <=
24356  cRowsInSet);
24357 
24358 
24359 *pcRowsObtained
24360  = 0;
24361 
24362 CComHeapPtr <
24363  HROW >
24364  rghRowsAllocated;
24365 
24366 if (*prghRows
24367  ==
24368  NULL)
24369  {
24370 
24371 DBROWOFFSET
24372  cHandlesToAlloc
24373  =
24374  cRowsFetched;
24375 
24376 
24377 rghRowsAllocated.
24378  Allocate
24379  (cHandlesToAlloc);
24380 
24381 if
24382  (rghRowsAllocated
24383  ==
24384  NULL)
24385  return
24386  E_OUTOFMEMORY;
24387 
24388 
24389 *prghRows =
24390  rghRowsAllocated;
24391 
24392 }
24393 
24394 
24395  // now fetch
24396  // the rows
24397  cRowsToFetch =
24398  cRows;
24399 
24400 
24401 while
24402  (cRowsToFetch
24403  > 0
24404  &&
24405  nCurrentRow
24406  >= 0
24407  &&
24408  nCurrentRow
24409  <=
24410  cRowsInSet)
24411  {
24412 
24413 if ((iStepSize == 1 && nCurrentRow == cRowsInSet) ||
24414 (iStepSize == -1 && nCurrentRow == 0))
24415  break;
24416 
24417 DBROWOFFSET lRow = nCurrentRow;
24418 
24419 if (iStepSize > 0)
24420  {
24421 
24422 while (true)
24423 
24424  {
24425 
24426 RowClass *
24427  pRow = NULL;
24428 
24429 RowClass::
24430  KeyType key =
24431  lRow + 1;
24432 
24433 bool bFound =
24434  m_rgRowHandles.
24435  Lookup (key,
24436  pRow);
24437 
24438 if (bFound
24439  && pRow
24440  !=
24441  NULL)
24442  {
24443 
24444 if (pRow->
24445  m_status
24446  ==
24447  DBPENDINGSTATUS_DELETED)
24448 
24449  {
24450 
24451 lRow++;
24452 
24453 ATLASSERT
24454  (lRow <
24455  cRowsInSet);
24456 
24457 continue;
24458 }
24459 
24460 }
24461 
24462 break;
24463 }
24464 
24465 }
24466 
24467  else
24468 
24469  {
24470 
24471 while (true)
24472 
24473  {
24474 
24475 lRow--;
24476 
24477 RowClass *
24478  pRow = NULL;
24479 
24480 RowClass::
24481  KeyType key =
24482  lRow + 1;
24483 
24484 bool bFound =
24485  m_rgRowHandles.
24486  Lookup (key,
24487  pRow);
24488 
24489 if (bFound
24490  && pRow
24491  !=
24492  NULL)
24493  {
24494 
24495 if (pRow->
24496  m_status
24497  ==
24498  DBPENDINGSTATUS_DELETED)
24499 
24500  {
24501 
24502 ATLASSERT
24503  (lRow >= 0);
24504 
24505 continue;
24506 }
24507 
24508 }
24509 
24510 break;
24511 }
24512 
24513 }
24514 
24515 
24516 ATLASSERT
24517  (lRow >= 0
24518  && lRow <
24519  cRowsInSet);
24520 
24521 
24522 hr =
24523  pT->
24524  CreateRow
24525  (lRow,
24526  *pcRowsObtained,
24527  *prghRows);
24528 
24529 
24530 if (FAILED
24531  (hr))
24532  {
24533 
24534 RefRows
24535  (*pcRowsObtained,
24536  *prghRows,
24537  NULL, NULL,
24538  FALSE);
24539 
24540 for (ULONG
24541  iRowDel
24542  = 0;
24543  iRowDel
24544  <
24545  *pcRowsObtained;
24546  iRowDel++)
24547 
24548  *prghRows
24549  [iRowDel] =
24550  NULL;
24551 
24552 *pcRowsObtained
24553  = 0;
24554 
24555 return hr;
24556 }
24557 
24558 
24559 __if_exists
24560  (T::
24561  Fire_OnRowsetChange)
24562 
24563  {
24564 
24565 if
24566  (!m_bExternalFetch)
24567 
24568  pT->
24569  Fire_OnRowsetChange
24570  (pT,
24571  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
24572 
24573 DBEVENTPHASE_DIDEVENT,
24574  TRUE);
24575 }
24576 
24577 
24578 cRowsToFetch--;
24579 
24580 if (iStepSize
24581  >
24582  0)
24583  nCurrentRow =
24584  lRow +
24585  iStepSize;
24586  else
24587 
24588 nCurrentRow = lRow;
24589 } // while
24590 
24591  // If we have
24592  // multiple
24593  // rows
24594  // fetched,
24595  // return one
24596  // event, per
24597  // the
24598  // specification
24599  // containing
24600  // all rows
24601  // activated.
24602  if
24603  (*pcRowsObtained
24604  >= 1)
24605  {
24606 
24607 __if_exists
24608  (T::
24609  Fire_OnRowsetChange)
24610 
24611  {
24612 
24613 CAtlArray <
24614  HROW >
24615  rgActivated;
24616 
24617 for (size_t
24618  ulActivated
24619  = 0;
24620  ulActivated
24621  <
24622  *pcRowsObtained;
24623  ulActivated++)
24624 
24625  {
24626 
24627  // This is a
24628  // bit of an
24629  // assumption
24630  // that all
24631  // newly
24632  // activated
24633  // rows would
24634  // have the
24635  // ref count
24636  // as 1.
24637  // Another
24638  // way to
24639  // solve
24640  // this
24641  // problem
24642  // would be
24643  // to modify
24644  // the
24645  // signature
24646  // of
24647  // CreateRow
24648  // to take
24649  // a
24650  // CAtlArray<HROW>
24651  // as a
24652  // parameter
24653  // and store
24654  // the
24655  // activated
24656  // rows.
24657  RowClass *
24658  pActiveRow;
24659 
24660 if
24661  (m_rgRowHandles.
24662  Lookup ((*prghRows)[ulActivated], pActiveRow) &&
24663 (pActiveRow != NULL && pActiveRow->m_dwRef == 1))
24664  {
24665 
24666 _ATLTRY
24667  {
24668 
24669 rgActivated.
24670  Add ((*prghRows)[ulActivated]);
24671 }
24672 
24673 _ATLCATCH (e)
24674 
24675  {
24676 
24677 _ATLDELETEEXCEPTION
24678  (e);
24679 
24680 return
24681  E_OUTOFMEMORY;
24682 
24683 }
24684 
24685 }
24686 
24687 }
24688 
24689 if
24690  (rgActivated.
24691  GetCount () >
24692  0)
24693  {
24694 
24695 pT->
24696  Fire_OnRowChange
24697  (pT,
24698  (DBCOUNTITEM)
24699  rgActivated.
24700  GetCount (),
24701  rgActivated.
24702  GetData (),
24703 
24704 DBREASON_ROW_ACTIVATE,
24705  DBEVENTPHASE_DIDEVENT,
24706  FALSE);
24707 }
24708 
24709 }
24710 
24711 }
24712 
24713 
24714 m_iRowset = nCurrentRow;
24715 if (*pcRowsObtained < (DBCOUNTITEM) cRows) // we
24716  // could
24717  // not
24718  // fetch
24719  // the
24720  // requested
24721  // #
24722  // of
24723  // rows
24724  hr =
24725  DB_S_ENDOFROWSET;
24726 
24727 
24728 if
24729  (SUCCEEDED
24730  (hr))
24731  rghRowsAllocated.
24732  Detach ();
24733 
24734 
24735 return hr;
24736 
24737 }
24738 
24739 
24740 STDMETHOD
24741  (GetNextRows)
24742  (HCHAPTER
24743  hReserved,
24744 
24745 DBROWOFFSET
24746  lRowsOffset,
24747 
24748 DBROWCOUNT
24749  cRows,
24750 
24751 DBCOUNTITEM
24752  *
24753  pcRowsObtained,
24754 
24755 HROW **
24756  prghRows)
24757  {
24758 
24759 
24760 if
24761  (m_bRemoveDeleted
24762  &&
24763  m_bIRowsetUpdate)
24764 
24765  return
24766  GetNextRowsSkipDeleted
24767  (hReserved,
24768  lRowsOffset,
24769  cRows,
24770  pcRowsObtained,
24771  prghRows);
24772 
24773 
24774 DBROWOFFSET
24775  lTmpRows =
24776  lRowsOffset;
24777 
24778 ATLTRACE
24779  (atlTraceDBProvider,
24780  2,
24781  _T
24782  ("IRowsetImpl::GetNextRows\n"));
24783 
24784 T * pT =
24785  (T *) this;
24786 
24787 
24788 __if_exists
24789  (T::
24790  Fire_OnRowChange)
24791 
24792  {
24793 
24794  // Check to
24795  // see if
24796  // someone is
24797  // in an
24798  // event
24799  // handler.
24800  // If we do,
24801  // then
24802  // we should
24803  // return
24804  // DB_E_NOTREENTRANT.
24805  if (!pT->
24806  IncrementMutex
24807  ())
24808  {
24809 
24810  // Note, we
24811  // can't set
24812  // this above
24813  // this block
24814  // because we
24815  // may
24816  // inadvertantly
24817  // reset
24818  // somebody
24819  // else's
24820  // pcRowsObtained
24821  if
24822  (pcRowsObtained
24823  !=
24824  NULL)
24825  *pcRowsObtained
24826  = 0;
24827 
24828 return
24829  DB_E_NOTREENTRANT;
24830 
24831 }
24832 
24833  else
24834 
24835 pT->
24836  DecrementMutex
24837  ();
24838 }
24839 
24840 
24841 if
24842  (pcRowsObtained
24843  !=
24844  NULL)
24845  *pcRowsObtained
24846  = 0;
24847 
24848 if (prghRows
24849  == NULL
24850  ||
24851  pcRowsObtained
24852  ==
24853  NULL)
24854  return
24855  E_INVALIDARG;
24856 
24857 if (cRows ==
24858  0)
24859  return S_OK;
24860 
24861 HRESULT hr =
24862  S_OK;
24863 
24864 T::
24865  ObjectLock
24866  cab (pT);
24867 
24868 if
24869  (lRowsOffset <
24870  0
24871  &&
24872  !m_bCanScrollBack)
24873 
24874  return
24875  DB_E_CANTSCROLLBACKWARDS;
24876 
24877 if (cRows < 0
24878  &&
24879  !m_bCanFetchBack)
24880 
24881  return
24882  DB_E_CANTFETCHBACKWARDS;
24883 
24884 
24885  // Calculate
24886  // # of rows
24887  // in set and
24888  // the base
24889  // fetch
24890  // position.
24891  // If the
24892  // rowset
24893  // is at its
24894  // head
24895  // position,
24896  // then
24897  // lRowOffset
24898  // < 0 means
24899  // moving
24900  // from the
24901  // BACK
24902  // of the
24903  // rowset and
24904  // not the
24905  // front.
24906 
24907 DBROWOFFSET
24908  cRowsInSet =
24909  (DBROWOFFSET)
24910  pT->
24911  m_rgRowData.
24912  GetCount ();
24913 
24914 
24915 if (((lRowsOffset == MINLONG_PTR) && (cRowsInSet != MINLONG_PTR))
24916  ||AbsVal (lRowsOffset) > cRowsInSet ||
24917 (AbsVal (lRowsOffset) == cRowsInSet && lRowsOffset < 0 && cRows < 0) ||
24918 (AbsVal (lRowsOffset) == cRowsInSet && lRowsOffset > 0 && cRows > 0))
24919  return DB_S_ENDOFROWSET;
24920 
24921  // In the
24922  // case where
24923  // the user
24924  // is moving
24925  // backwards
24926  // after
24927  // moving
24928  // forwards,
24929  // we do not
24930  // wrap
24931  // around to
24932  // the end of
24933  // the
24934  // rowset.
24935  if ((m_iRowset
24936  == 0
24937  &&
24938  !m_bReset
24939  && cRows
24940  < 0)
24941  ||
24942 
24943 ((m_iRowset + lRowsOffset) > cRowsInSet) ||
24944 (m_iRowset == cRowsInSet && lRowsOffset >= 0 && cRows > 0))
24945  return DB_S_ENDOFROWSET;
24946 
24947  // Fire
24948  // events for
24949  // OKTODO and
24950  // ABOUTTODO
24951  // after all
24952  // validation
24953  // has taken
24954  // place but
24955  // before any
24956  // permanent
24957  // changes to
24958  // the rowset
24959  // state take
24960  // place
24961  __if_exists
24962  (T::
24963  Fire_OnRowsetChange)
24964 
24965  {
24966 
24967  // Only fire
24968  // these
24969  // events if
24970  // we're not
24971  // being
24972  // called by
24973  // a
24974  // bookmark
24975  // operation
24976  // (which is
24977  // why
24978  // m_bExternalFetch
24979  // would be
24980  // set to
24981  // true)
24982  if
24983  (!m_bExternalFetch)
24984 
24985  {
24986 
24987 HRESULT
24988  hrNotify =
24989  pT->
24990  Fire_OnRowsetChange
24991  (pT,
24992 
24993 DBREASON_ROWSET_FETCHPOSITIONCHANGE,
24994  DBEVENTPHASE_OKTODO,
24995  FALSE);
24996 
24997 if (hrNotify
24998  ==
24999  S_FALSE)
25000 
25001  return
25002  DB_E_CANCELED;
25003 
25004  else
25005 
25006  {
25007 
25008 hrNotify =
25009  pT->
25010  Fire_OnRowsetChange
25011  (pT,
25012  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25013 
25014 DBEVENTPHASE_ABOUTTODO,
25015  FALSE);
25016 
25017 if (hrNotify
25018  ==
25019  S_FALSE)
25020 
25021  return
25022  DB_E_CANCELED;
25023 
25024  else
25025 
25026  {
25027 
25028 hrNotify =
25029  pT->
25030  Fire_OnRowsetChange
25031  (pT,
25032  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25033 
25034 DBEVENTPHASE_SYNCHAFTER,
25035  FALSE);
25036 
25037 if (hrNotify
25038  ==
25039  S_FALSE)
25040 
25041  return
25042  DB_E_CANCELED;
25043 
25044 }
25045 
25046 }
25047 
25048 }
25049 
25050 }
25051 
25052 
25053  // Note, if
25054  // m_bReset,
25055  // m_iRowset
25056  // must be 0
25057  if
25058  (lRowsOffset <
25059  0
25060  && m_bReset)
25061 
25062  m_iRowset =
25063  cRowsInSet;
25064 
25065 
25066 int
25067  iStepSize =
25068  cRows >=
25069  0 ? 1 : -1;
25070 
25071  // If cRows
25072  // ==
25073  // MINLONG_PTR,
25074  // we can't
25075  // use ABS on
25076  // it.
25077  // Therefore,
25078  // we reset
25079  // it
25080  // to a value
25081  // just
25082  // greater
25083  // than
25084  // cRowsInSet
25085  if (cRows == MINLONG_PTR && cRowsInSet != MINLONG_PTR)
25086  cRows = cRowsInSet + 2; // set
25087  // the
25088  // value
25089  // to
25090  // something
25091  // we
25092  // can
25093  // deal
25094  // with
25095  else
25096 
25097 cRows =
25098  AbsVal
25099  (cRows);
25100 
25101 
25102 if
25103  (iStepSize < 0
25104  && m_iRowset
25105  == 0
25106  && m_bReset
25107  &&
25108  lRowsOffset
25109  <=
25110  0)
25111  m_iRowset =
25112  cRowsInSet;
25113 
25114 
25115 lRowsOffset
25116  += m_iRowset;
25117 
25118 
25119 *pcRowsObtained
25120  = 0;
25121 
25122 CComHeapPtr <
25123  HROW >
25124  rghRowsAllocated;
25125 
25126 if (*prghRows
25127  ==
25128  NULL)
25129  {
25130 
25131 DBROWOFFSET
25132  cHandlesToAlloc
25133  =
25134  __min
25135  (cRowsInSet,
25136  cRows);
25137 
25138 if (iStepSize
25139  == 1
25140  &&
25141  (cRowsInSet
25142  -
25143  lRowsOffset)
25144  <
25145  cHandlesToAlloc)
25146 
25147  cHandlesToAlloc
25148  =
25149  cRowsInSet -
25150  lRowsOffset;
25151 
25152 if (iStepSize
25153  == -1
25154  &&
25155  lRowsOffset
25156  <
25157  cHandlesToAlloc)
25158 
25159  cHandlesToAlloc
25160  = lRowsOffset;
25161 
25162 
25163 rghRowsAllocated.
25164  Allocate
25165  (cHandlesToAlloc);
25166 
25167 if
25168  (rghRowsAllocated
25169  ==
25170  NULL)
25171  return
25172  E_OUTOFMEMORY;
25173 
25174 *prghRows =
25175  rghRowsAllocated;
25176 
25177 }
25178 
25179 
25180 while ((lRowsOffset >= 0 && cRows != 0) &&
25181 ((lRowsOffset < cRowsInSet) || (lRowsOffset <= cRowsInSet && iStepSize < 0)))
25182  {
25183 
25184  // cRows >
25185  // cRowsInSet
25186  // &&
25187  // iStepSize
25188  // < 0
25189  if
25190  (lRowsOffset
25191  == 0
25192  && cRows > 0
25193  && iStepSize
25194  < 0)
25195  break;
25196 
25197 
25198  // in the
25199  // case where
25200  // we have
25201  // iStepSize
25202  // < 0, move
25203  // the row
25204  // back
25205  // further
25206  // because we
25207  // want the
25208  // previous
25209  // row
25210  DBROWOFFSET
25211  lRow =
25212  lRowsOffset;
25213 
25214 if ((lRowsOffset == 0) && (lTmpRows == 0) && (iStepSize < 0))
25215  lRow = cRowsInSet;
25216 
25217 if (iStepSize < 0)
25218  lRow += iStepSize;
25219 
25220 hr = pT->CreateRow (lRow, *pcRowsObtained, *prghRows);
25221 
25222 if (FAILED (hr))
25223  {
25224 
25225 RefRows
25226  (*pcRowsObtained,
25227  *prghRows,
25228  NULL, NULL,
25229  FALSE);
25230 
25231 for (ULONG
25232  iRowDel
25233  = 0;
25234  iRowDel
25235  <
25236  *pcRowsObtained;
25237  iRowDel++)
25238 
25239  *prghRows
25240  [iRowDel] =
25241  NULL;
25242 
25243 *pcRowsObtained
25244  = 0;
25245 
25246 return hr;
25247 }
25248 
25249 
25250 __if_exists
25251  (T::
25252  Fire_OnRowsetChange)
25253 
25254  {
25255 
25256 if
25257  (!m_bExternalFetch)
25258 
25259  pT->
25260  Fire_OnRowsetChange
25261  (pT,
25262  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25263 
25264 DBEVENTPHASE_DIDEVENT,
25265  TRUE);
25266 }
25267 
25268 
25269 cRows--;
25270 
25271 lRowsOffset
25272  += iStepSize;
25273 
25274 }
25275 
25276 
25277  // If we have
25278  // multiple
25279  // rows
25280  // fetched,
25281  // return one
25282  // event, per
25283  // the
25284  // specification
25285  // containing
25286  // all rows
25287  // activated.
25288  if
25289  (*pcRowsObtained
25290  >= 1)
25291  {
25292 
25293 __if_exists
25294  (T::
25295  Fire_OnRowsetChange)
25296 
25297  {
25298 
25299 CAtlArray <
25300  HROW >
25301  rgActivated;
25302 
25303 for (size_t
25304  ulActivated
25305  = 0;
25306  ulActivated
25307  <
25308  *pcRowsObtained;
25309  ulActivated++)
25310 
25311  {
25312 
25313  // This is a
25314  // bit of an
25315  // assumption
25316  // that all
25317  // newly
25318  // activated
25319  // rows would
25320  // have the
25321  // ref count
25322  // as 1.
25323  // Another
25324  // way to
25325  // solve
25326  // this
25327  // problem
25328  // would be
25329  // to modify
25330  // the
25331  // signature
25332  // of
25333  // CreateRow
25334  // to take
25335  // a
25336  // CAtlArray<HROW>
25337  // as a
25338  // parameter
25339  // and store
25340  // the
25341  // activated
25342  // rows.
25343  RowClass *
25344  pActiveRow;
25345 
25346 if
25347  (m_rgRowHandles.
25348  Lookup ((*prghRows)[ulActivated], pActiveRow) &&
25349 (pActiveRow != NULL && pActiveRow->m_dwRef == 1))
25350  {
25351 
25352 _ATLTRY
25353  {
25354 
25355 rgActivated.
25356  Add ((*prghRows)[ulActivated]);
25357 }
25358 
25359 _ATLCATCH (e)
25360 
25361  {
25362 
25363 _ATLDELETEEXCEPTION
25364  (e);
25365 
25366 return
25367  E_OUTOFMEMORY;
25368 
25369 }
25370 
25371 }
25372 
25373 }
25374 
25375 if
25376  (rgActivated.
25377  GetCount () >
25378  0)
25379  {
25380 
25381 pT->
25382  Fire_OnRowChange
25383  (pT,
25384  (DBCOUNTITEM)
25385  rgActivated.
25386  GetCount (),
25387  rgActivated.
25388  GetData (),
25389 
25390 DBREASON_ROW_ACTIVATE,
25391  DBEVENTPHASE_DIDEVENT,
25392  FALSE);
25393 }
25394 
25395 }
25396 
25397 }
25398 
25399 
25400 m_iRowset =
25401  lRowsOffset;
25402 
25403 if ((lRowsOffset >= cRowsInSet && cRows) || (lRowsOffset < 0 && cRows) ||
25404 (lRowsOffset == 0 && cRows > 0 && iStepSize < 0))
25405  hr = DB_S_ENDOFROWSET;
25406 
25407 if (SUCCEEDED (hr))
25408  rghRowsAllocated.Detach ();
25409 return hr;
25410 }
25411 
25412 
25413 STDMETHOD
25414  (ReleaseRows)
25415  (DBCOUNTITEM
25416  cRows,
25417 
25418 const HROW
25419  rghRows[],
25420 
25421 DBROWOPTIONS
25422  rgRowOptions
25423  [],
25424 
25425 DBREFCOUNT
25426  rgRefCounts
25427  [],
25428 
25429 DBROWSTATUS
25430  rgRowStatus
25431  [])
25432  {
25433 
25434 ATLTRACE
25435  (atlTraceDBProvider,
25436  2,
25437  _T
25438  ("IRowsetImpl::ReleaseRows\n"));
25439 
25440 
25441 __if_exists
25442  (T::
25443  Fire_OnRowChange)
25444 
25445  {
25446 
25447 T * pT =
25448  (T *) this;
25449 
25450  // Check to
25451  // see if
25452  // someone is
25453  // in an
25454  // event
25455  // handler.
25456  // If we do,
25457  // then
25458  // we should
25459  // return
25460  // DB_E_NOTREENTRANT.
25461  if (!pT->
25462  IncrementMutex
25463  ())
25464  return
25465  DB_E_NOTREENTRANT;
25466 
25467  else
25468 
25469 pT->
25470  DecrementMutex
25471  ();
25472 }
25473 
25474 
25475 if (cRows ==
25476  0)
25477  return S_OK;
25478 
25479 rgRowOptions;
25480 
25481 return
25482  RefRows
25483  (cRows,
25484  rghRows,
25485  rgRefCounts,
25486  rgRowStatus,
25487  FALSE);
25488 }
25489 
25490 
25491 STDMETHOD (RestartPosition) (HCHAPTER /* hReserved
25492  */
25493  )
25494  {
25495 
25496 ATLTRACE
25497  (atlTraceDBProvider,
25498  2,
25499  _T
25500  ("IRowsetImpl::RestartPosition\n"));
25501 
25502 
25503 T * pT =
25504  (T *) this;
25505 
25506 
25507 __if_exists
25508  (T::
25509  Fire_OnRowsetChange)
25510 
25511  {
25512 
25513  // Check to
25514  // see if
25515  // someone is
25516  // in an
25517  // event
25518  // handler.
25519  // If we do,
25520  // then
25521  // we should
25522  // return
25523  // DB_E_NOTREENTRANT.
25524  if (!pT->
25525  IncrementMutex
25526  ())
25527  return
25528  DB_E_NOTREENTRANT;
25529 
25530  else
25531 
25532 pT->
25533  DecrementMutex
25534  ();
25535 
25536 
25537 
25538 bool
25539  bNeedEvents =
25540  ((m_iRowset !=
25541  0
25542  ||
25543  !m_bReset))
25544  ? true :
25545  false;
25546 
25547  // Only fire
25548  // the events
25549  // iff. we
25550  // are
25551  // actually
25552  // causing a
25553  // reset
25554  if
25555  (bNeedEvents)
25556 
25557  {
25558 
25559 HRESULT
25560  hrNotify =
25561  pT->
25562  Fire_OnRowsetChange
25563  (pT,
25564 
25565 DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25566  DBEVENTPHASE_OKTODO,
25567  FALSE);
25568 
25569 if (hrNotify
25570  ==
25571  S_FALSE)
25572 
25573  return
25574  DB_E_CANCELED;
25575 
25576  else
25577 
25578  {
25579 
25580 hrNotify =
25581  pT->
25582  Fire_OnRowsetChange
25583  (pT,
25584  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25585 
25586 DBEVENTPHASE_ABOUTTODO,
25587  FALSE);
25588 
25589 if (hrNotify
25590  ==
25591  S_FALSE)
25592 
25593  return
25594  DB_E_CANCELED;
25595 
25596  else
25597 
25598  {
25599 
25600 hrNotify =
25601  pT->
25602  Fire_OnRowsetChange
25603  (pT,
25604  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25605 
25606 DBEVENTPHASE_SYNCHAFTER,
25607  FALSE);
25608 
25609 if (hrNotify
25610  ==
25611  S_FALSE)
25612 
25613  return
25614  DB_E_CANCELED;
25615 
25616 }
25617 
25618 }
25619 
25620 
25621 }
25622 
25623 }
25624 
25625 
25626  // Check to
25627  // see if
25628  // DBPROP_CANHOLDROWS
25629  // is set to
25630  // false. In
25631  // this
25632  // case,
25633  // return a
25634  // DB_E_ROWSNOTRELEASED.
25635  CComVariant
25636  varHoldRows;
25637 
25638 HRESULT hr =
25639  pT->
25640  GetPropValue
25641  (&DBPROPSET_ROWSET,
25642  DBPROP_CANHOLDROWS,
25643 
25644 &varHoldRows);
25645 
25646 
25647 if (FAILED
25648  (hr)
25649  ||
25650  varHoldRows.
25651  boolVal
25652  ==
25654 
25655  {
25656 
25657 if
25658  (m_rgRowHandles.
25659  GetCount () >
25660  0)
25661  {
25662 
25663 RowClass *
25664  pRow = NULL;
25665 
25666 POSITION pos
25667  =
25668  pT->
25669  m_rgRowHandles.
25670  GetStartPosition
25671  ();
25672 
25673 
25674 while (pos
25675  !=
25676  NULL)
25677 
25678  {
25679 
25680 MapClass::
25681  CPair *
25682  pPair =
25683  pT->
25684  m_rgRowHandles.
25685  GetNext (pos);
25686 
25687 ATLASSERT
25688  (pPair !=
25689  NULL);
25690 
25691 HROW hRow =
25692  pPair->m_key;
25693 
25694 bool bFound =
25695  pT->
25696  m_rgRowHandles.
25697  Lookup (hRow,
25698  pRow);
25699 
25700 
25701 if (bFound
25702  && pRow
25703  != NULL
25704  &&
25705 
25706 pRow->
25707  m_status
25708  !=
25709  DBPENDINGSTATUS_UNCHANGED)
25710 
25711  {
25712 
25713 __if_exists
25714  (T::
25715  Fire_OnRowsetChange)
25716 
25717  {
25718 
25719 if
25720  (bNeedEvents)
25721 
25722  {
25723 
25724 pT->
25725  Fire_OnRowsetChange
25726  (pT,
25727  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25728 
25729 DBEVENTPHASE_FAILEDTODO,
25730  TRUE);
25731 }
25732 
25733 }
25734 
25735 
25736 return
25737  DB_E_ROWSNOTRELEASED;
25738 
25739 }
25740 
25741 }
25742 
25743 }
25744 
25745 }
25746 
25747 
25748 m_iRowset =
25749  0;
25750 
25751 m_bReset =
25752  true;
25753 
25754 __if_exists
25755  (T::
25756  Fire_OnRowsetChange)
25757 
25758  {
25759 
25760  // listener
25761  // must
25762  // comply so
25763  // blow off
25764  // ret val.
25765  if
25766  (bNeedEvents)
25767 
25768  pT->
25769  Fire_OnRowsetChange
25770  (pT,
25771  DBREASON_ROWSET_FETCHPOSITIONCHANGE,
25772 
25773 DBEVENTPHASE_DIDEVENT,
25774  TRUE);
25775 }
25776 
25777 return S_OK;
25778 }
25779 
25780 
25781 MapClass m_rgRowHandles;
25782 DBROWOFFSET m_iRowset; // cursor
25783  unsigned m_bCanScrollBack: 1;
25784 unsigned m_bCanFetchBack: 1;
25785 unsigned m_bRemoveDeleted: 1; // DBPROP_REMOVEDELETED
25786  unsigned m_bIRowsetUpdate: 1; // DBPROP_IRowsetUpdate
25787 unsigned m_bReset: 1;
25788 unsigned m_bExternalFetch: 1;
25789 };
25790 
25791 
25792 template < class T, class RowsetInterface,
25793 class RowClass = CSimpleRow,
25794 class MapClass = CAtlMap < RowClass::KeyType, RowClass * >,
25795 class BookmarkKeyType = LONG, class BookmarkType = LONG,
25796 class BookmarkMapClass = CAtlMap < RowClass::KeyType, RowClass * >>
25797 class ATL_NO_VTABLE IRowsetLocateImpl:public
25798  IRowsetImpl <
25799  T,
25800  RowsetInterface,
25801  RowClass,
25802  MapClass >
25803  {
25804 
25805 public:
25806 STDMETHOD (Compare) (HCHAPTER /* hReserved
25807  */
25808  ,
25809  DBBKMARK
25810  cbBookmark1,
25811 
25812 const
25813  BYTE
25814  *
25815  pBookmark1,
25816  DBBKMARK
25817  cbBookmark2,
25818  const
25819  BYTE
25820  *
25821  pBookmark2,
25822 
25823 DBCOMPARE
25824  *
25825  pComparison)
25826 
25827  {
25828 
25829 ATLTRACE
25830  (atlTraceDBProvider,
25831  2,
25832  _T
25833  ("IRowsetLocateImpl::Compare\n"));
25834 
25835 
25836 T * pT =
25837  (T *) this;
25838 
25839 
25840 __if_exists
25841  (T::
25842  Fire_OnRowChange)
25843 
25844  {
25845 
25846  // Check to
25847  // see if
25848  // someone is
25849  // in an
25850  // event
25851  // handler.
25852  // If we do,
25853  // then
25854  // we should
25855  // return
25856  // DB_E_NOTREENTRANT.
25857  if (!pT->
25858  IncrementMutex
25859  ())
25860  return
25861  DB_E_NOTREENTRANT;
25862 
25863  else
25864 
25865 pT->
25866  DecrementMutex
25867  ();
25868 }
25869 
25870 
25871 
25872  // Validate
25873  // input
25874  // parameters
25875  if
25876  (pComparison
25877  ==
25878  NULL)
25879  return
25880  E_INVALIDARG;
25881 
25882 
25883  // ValidateBookmark
25884  // catches
25885  // the
25886  // cbBookmark
25887  // == 0 and
25888  // the
25889  // pBookmark
25890  // == NULL --
25891  // E_INVALIDARG
25892  // cases
25893  HRESULT hr =
25894  ValidateBookmark
25895  (cbBookmark1,
25896  pBookmark1);
25897 
25898 if (hr !=
25899  S_OK)
25900  return hr;
25901 
25902 
25903 hr =
25904  ValidateBookmark
25905  (cbBookmark2,
25906  pBookmark2);
25907 
25908 if (hr !=
25909  S_OK)
25910  return hr;
25911 
25912  // Return the
25913  // value
25914  // based on
25915  // the
25916  // bookmark
25917  // values.
25918  // Be sure
25919  // that
25920  // they are
25921  // not
25922  // specials
25923  // in which
25924  // case go
25925  // below
25926  if ((*pBookmark1 == *pBookmark2) && (cbBookmark1 != 1) && (cbBookmark2 != 1))
25927  {
25928 
25929 *pComparison
25930  =
25931  DBCOMPARE_EQ;
25932 
25933 return S_OK;
25934 
25935 }
25936 
25937 
25938  // Determine
25939  // if we are
25940  // using
25941  // ordered or
25942  // unorder
25943  // bookmarks
25944  CComVariant
25945  varOrdered;
25946 
25947 HRESULT
25948  hrProps =
25949  pT->
25950  GetPropValue
25951  (&DBPROPSET_ROWSET,
25952  DBPROP_ORDEREDBOOKMARKS,
25953 
25954 &varOrdered);
25955 
25956 
25957 if ((*pBookmark1 == DBBMK_FIRST && cbBookmark1 == 1) ||
25958 (*pBookmark1 == DBBMK_LAST && cbBookmark1 == 1) ||
25959 (*pBookmark2 == DBBMK_FIRST && cbBookmark2 == 1) ||
25960 (*pBookmark2 == DBBMK_LAST && cbBookmark2 == 1) ||
25961 (FAILED (hrProps)) ||
25962 (varOrdered.boolVal == ATL_VARIANT_FALSE))
25963  {
25964 
25965  // If the
25966  // bookmarks
25967  // are
25968  // 'specials'
25969  // DBBMK_FIRST
25970  // or
25971  // DBBMK_LAST
25972  // or the
25973  // bookmarks
25974  // are
25975  // unordered,
25976  // then we
25977  // return NE
25978  // instead of
25979  // GT or LT.
25980  if
25981  (*pBookmark1
25982  ==
25983  *pBookmark2)
25984 
25985  *pComparison
25986  =
25987  DBCOMPARE_EQ;
25988 
25989  else
25990 
25991 *pComparison
25992  =
25993  DBCOMPARE_NE;
25994 
25995 }
25996 
25997  else
25998 
25999  {
26000 
26001  // We have
26002  // valid
26003  // bookmarks
26004  // which are
26005  // not
26006  // special
26007  // values.
26008  // Since we
26009  // assume
26010  // that
26011  // bookmarks
26012  // are
26013  // ordered,
26014  // we'll
26015  // return
26016  // the
26017  if (*
26018  (DBBKMARK
26019  *)
26020  pBookmark1
26021  <
26022  *(DBBKMARK
26023  *)
26024  pBookmark2)
26025 
26026  *pComparison
26027  =
26028  DBCOMPARE_LT;
26029 
26030  else
26031  if (*
26032  (DBBKMARK
26033  *)
26034  pBookmark1
26035  >
26036  *(DBBKMARK
26037  *)
26038  pBookmark2)
26039 
26040  *pComparison
26041  =
26042  DBCOMPARE_GT;
26043 
26044  else
26045 
26046 *pComparison
26047  =
26048  DBCOMPARE_EQ;
26049 
26050 }
26051 
26052 
26053 return S_OK;
26054 }
26055 
26056 
26057 STDMETHOD (GetRowsAt) (HWATCHREGION /* hReserved1
26058  */
26059  ,
26060  HCHAPTER
26061  hReserved2,
26062 
26063 DBBKMARK
26064  cbBookmark,
26065  const
26066  BYTE
26067  *
26068  pBookmark,
26069  DBROWOFFSET
26070  lRowsOffset,
26071 
26072 DBROWCOUNT
26073  cRows,
26074  DBCOUNTITEM
26075  *
26076  pcRowsObtained,
26077  HROW
26078  **
26079  prghRows)
26080 
26081  {
26082 
26083 ATLTRACE
26084  (atlTraceDBProvider,
26085  2,
26086  _T
26087  ("IRowsetLocateImpl::GetRowsAt\n"));
26088 
26089 
26090 T * pT =
26091  (T *) this;
26092 
26093 
26094 __if_exists
26095  (T::
26096  Fire_OnRowChange)
26097 
26098  {
26099 
26100  // Check to
26101  // see if
26102  // someone is
26103  // in an
26104  // event
26105  // handler.
26106  // If we do,
26107  // then
26108  // we should
26109  // return
26110  // DB_E_NOTREENTRANT.
26111  if (!pT->
26112  IncrementMutex
26113  ())
26114  return
26115  DB_E_NOTREENTRANT;
26116 
26117  else
26118 
26119 pT->
26120  DecrementMutex
26121  ();
26122 }
26123 
26124 
26125  // TODO:
26126  // Change
26127  // this to a
26128  // regular
26129  // CComCriticalSection
26130  // call
26131  T::
26132  ObjectLock
26133  cab (pT);
26134 
26135  // Check
26136  // input
26137  // parameters
26138  if
26139  (pcRowsObtained
26140  ==
26141  NULL)
26142  return
26143  E_INVALIDARG;
26144 
26145 
26146 *pcRowsObtained
26147  = 0;
26148 
26149 
26150 if
26151  (cbBookmark ==
26152  0
26153  || pBookmark
26154  == NULL
26155  || prghRows
26156  ==
26157  NULL)
26158  return
26159  E_INVALIDARG;
26160 
26161 
26162  // Check
26163  // bookmark
26164  HRESULT hr =
26165  ValidateBookmark
26166  (cbBookmark,
26167  pBookmark);
26168 
26169 if (hr !=
26170  S_OK)
26171  return hr;
26172 
26173  // Set the
26174  // current
26175  // row
26176  // position
26177  // to the
26178  // bookmark.
26179  // Handle
26180  // any
26181  // normal
26182  // values
26183 
26184  // We need to
26185  // handle the
26186  // offset as
26187  // the start
26188  // position
26189  // is
26190  // defined
26191  // as the
26192  // bookmark +
26193  // offset.
26194  // If the
26195  // offset is
26196  // negative,
26197  // and we
26198  // do not
26199  // have
26200  // m_bCanScrollBack
26201  // then
26202  // return an
26203  // error.
26204  // The
26205  // GetNextRows
26206  // function
26207  // handles
26208  // the case
26209  // where
26210  // cRows is
26211  // negative
26212  // and we
26213  // don't have
26214  // m_bCanFetchBack
26215  // set.
26216  if (lRowsOffset < 0 && !m_bCanScrollBack)
26217  return DB_E_CANTSCROLLBACKWARDS;
26218 
26219 DBROWOFFSET iRowsetTemp = m_iRowset; // Cache
26220  // the
26221  // current
26222  // rowset
26223  //
26224 
26225  // Determine
26226  // if this
26227  // row is
26228  // deleted or
26229  // not.
26230  size_t
26231  lBookmarkIndex
26232  =
26233  (size_t)
26234  (*pBookmark);
26235 
26236 
26237  // -1 is
26238  // uniform
26239  // value for
26240  // a deleted
26241  // bookmark
26242  if (cbBookmark
26243  != 1)
26244  {
26245 
26246 if
26247  (m_rgBookmarks
26248  [lBookmarkIndex]
26249  == -1)
26250  {
26251 
26252 m_iRowset =
26253  iRowsetTemp;
26254 
26255 return
26256  DB_E_BADBOOKMARK;
26257 
26258 }
26259 
26260  else
26261 
26262  {
26263 
26264 m_iRowset =
26265  m_rgBookmarks
26266  [lBookmarkIndex];
26267 
26268 }
26269 
26270 }
26271 
26272 
26273 if ((cbBookmark == 1) && (*pBookmark == DBBMK_FIRST))
26274  m_iRowset = 1;
26275 
26276 if ((cbBookmark == 1) && (*pBookmark == DBBMK_LAST))
26277  m_iRowset = (DBROWOFFSET) pT->m_rgRowData.GetCount ();
26278 
26279  // Set the
26280  // start
26281  // position
26282  // to
26283  // m_iRowset
26284  // +
26285  // lRowsOffset
26286  m_iRowset +=
26287  lRowsOffset;
26288 
26289 
26290 if
26291  (lRowsOffset
26292  >=
26293  0)
26294  (cRows
26295  >=
26296  0) ?
26297  m_iRowset -=
26298  1 : m_iRowset
26299  += 0;
26300  else
26301 
26302 (cRows >=
26303  0) ?
26304  m_iRowset -=
26305  1 : m_iRowset
26306  += 0;
26307 // (lRowsOffset >= 0) ? m_iRowset -= 1 : m_iRowset += 1;
26308 
26309  // BUG: If we
26310  // get
26311  // DBBMK_FIRST
26312  // and
26313  // lRowsOffset
26314  // == -1,
26315  // then we
26316  // set
26317  // m_iRowset
26318  // to
26319  // 0xFFFFFFFF.
26320 
26321 if (m_iRowset
26322  < 0
26323  ||
26324  m_iRowset
26325  >
26326  (DBROWOFFSET)
26327  pT->
26328  m_rgRowData.
26329  GetCount
26330  ())
26331  {
26332 
26333 m_iRowset =
26334  iRowsetTemp;
26335 
26336 return
26337  DB_S_ENDOFROWSET;
26338 
26339 }
26340 
26341 
26342  // Call
26343  // IRowsetImpl::GetNextRows
26344  // to
26345  // actually
26346  // get the
26347  // rows.
26348  m_bExternalFetch
26349  = true;
26350 
26351 hr =
26352  GetNextRows
26353  (hReserved2,
26354  0, cRows,
26355  pcRowsObtained,
26356  prghRows);
26357 
26358 m_bExternalFetch
26359  = false;
26360 
26361  // If we have
26362  // multiple
26363  // rows
26364  // fetched,
26365  // return one
26366  // event, per
26367  // the
26368  // specification
26369  // containing
26370  // all rows
26371  // activated.
26372  if
26373  (*pcRowsObtained
26374  >= 1)
26375  {
26376 
26377 __if_exists
26378  (T::
26379  Fire_OnRowsetChange)
26380 
26381  {
26382 
26383 CAtlArray <
26384  HROW >
26385  rgActivated;
26386 
26387 for (ULONG
26388  ulActivated
26389  = 0;
26390  ulActivated
26391  <
26392  *pcRowsObtained;
26393  ulActivated++)
26394 
26395  {
26396 
26397  // This is a
26398  // bit of an
26399  // assumption
26400  // that all
26401  // newly
26402  // activated
26403  // rows would
26404  // have the
26405  // ref count
26406  // as 1.
26407  // Another
26408  // way to
26409  // solve
26410  // this
26411  // problem
26412  // would be
26413  // to modify
26414  // the
26415  // signature
26416  // of
26417  // CreateRow
26418  // to take
26419  // a
26420  // CAtlArray<HROW>
26421  // as a
26422  // parameter
26423  // and store
26424  // the
26425  // activated
26426  // rows.
26427  RowClass *
26428  pActiveRow;
26429 
26430 bool bFound =
26431  m_rgRowHandles.
26432  Lookup ((*prghRows)[ulActivated], pActiveRow);
26433 if (bFound && pActiveRow != NULL && pActiveRow->m_dwRef == 1)
26434  {
26435 
26436 _ATLTRY
26437  {
26438 
26439 rgActivated.
26440  Add ((*prghRows)[ulActivated]);
26441 }
26442 
26443 _ATLCATCH (e)
26444 
26445  {
26446 
26447 _ATLDELETEEXCEPTION
26448  (e);
26449 
26450 return
26451  E_OUTOFMEMORY;
26452 
26453 }
26454 
26455 }
26456 
26457 }
26458 
26459 if
26460  (rgActivated.
26461  GetCount () >
26462  0)
26463  {
26464 
26465 pT->
26466  Fire_OnRowChange
26467  (pT,
26468  (DBCOUNTITEM)
26469  rgActivated.
26470  GetCount (),
26471  rgActivated.
26472  GetData (),
26473 
26474 DBREASON_ROW_ACTIVATE,
26475  DBEVENTPHASE_DIDEVENT,
26476  FALSE);
26477 }
26478 
26479 }
26480 
26481 }
26482 
26483 
26484 m_iRowset =
26485  iRowsetTemp;
26486 
26487 return hr;
26488 }
26489 
26490 
26491 STDMETHOD (GetRowsByBookmark) (HCHAPTER /* hReserved
26492  */
26493  ,
26494  DBCOUNTITEM
26495  cRows,
26496 
26497 const
26498  DBBKMARK
26499  rgcbBookmarks
26500  [],
26501  const
26502  BYTE
26503  *
26504  rgpBookmarks
26505  [],
26506 
26507 HROW
26508  rghRows
26509  [],
26510  DBROWSTATUS
26511  rgRowStatus
26512  [])
26513 
26514  {
26515 
26516 HRESULT hr =
26517  S_OK;
26518 
26519 ATLTRACE
26520  (atlTraceDBProvider,
26521  2,
26522  _T
26523  ("IRowsetLocateImpl::GetRowsByBookmark\n"));
26524 
26525 bool bErrors
26526  = false;
26527 
26528 bool bSuccess
26529  = false;
26530 
26531 
26532 T * pT =
26533  (T *) this;
26534 
26535 
26536 __if_exists
26537  (T::
26538  Fire_OnRowChange)
26539 
26540  {
26541 
26542  // Check to
26543  // see if
26544  // someone is
26545  // in an
26546  // event
26547  // handler.
26548  // If we do,
26549  // then
26550  // we should
26551  // return
26552  // DB_E_NOTREENTRANT.
26553  if (!pT->
26554  IncrementMutex
26555  ())
26556  return
26557  DB_E_NOTREENTRANT;
26558 
26559  else
26560 
26561 pT->
26562  DecrementMutex
26563  ();
26564 }
26565 
26566 
26567 T::ObjectLock cab (pT);
26568 if (rgcbBookmarks == NULL || rgpBookmarks == NULL || rghRows == NULL)
26569  return E_INVALIDARG;
26570 
26571 if (cRows == 0)
26572  return S_OK; // No
26573  // rows
26574  // fetched
26575  // in
26576  // this
26577  // case.
26578 
26579 memset
26580  (rghRows, 0,
26581  sizeof (HROW)
26582  * cRows);
26583 
26584 for (size_t l
26585  = 0;
26586  l <
26587  cRows;
26588  l++)
26589  {
26590 
26591  // Validate
26592  // each
26593  // bookmark
26594  // before
26595  // fetching
26596  // the row.
26597  // Note, it
26598  // is
26599  // an error
26600  // for the
26601  // bookmark
26602  // to be one
26603  // of the
26604  // standard
26605  // values
26606  const BYTE *
26607  pBookmark =
26608  rgpBookmarks
26609  [l];
26610 
26611 hr =
26612  ValidateBookmark
26613  (rgcbBookmarks
26614  [l],
26615  pBookmark);
26616 
26617 if ((hr !=
26618  S_OK)
26619  ||
26620 
26621  (*pBookmark
26622  ==
26623  DBBMK_FIRST
26624  &&
26625  rgcbBookmarks
26626  [l] ==
26627  1)
26628  ||
26629 
26630  (*pBookmark
26631  ==
26632  DBBMK_LAST
26633  &&
26634  rgcbBookmarks
26635  [l] ==
26636  1))
26637  {
26638 
26639 bErrors |=
26640  true;
26641 
26642 if
26643  (rgRowStatus
26644  != NULL)
26645  {
26646 
26647 rgRowStatus
26648  [l] =
26649  DBROWSTATUS_E_INVALID;
26650 
26651 continue;
26652 }
26653 
26654 }
26655 
26656 
26657  // Determine
26658  // if this
26659  // row is
26660  // deleted or
26661  // not by
26662  // first
26663  // looking in
26664  // our cache
26665  DBROWCOUNT lBookmarkIndex = *(DBROWCOUNT *) pBookmark;
26666 if (m_rgBookmarks[lBookmarkIndex] == -1) // Uniform
26667  // value
26668  // for
26669  // invalid
26670  // row
26671  {
26672 
26673 if
26674  (rgRowStatus
26675  !=
26676  NULL)
26677  rgRowStatus[l]
26678  =
26679  DBROWSTATUS_E_INVALID;
26680 
26681 
26682 bErrors |=
26683  true;
26684 
26685 continue;
26686 }
26687 
26688 
26689  // Fetch the
26690  // row, we
26691  // now that
26692  // it is a
26693  // valid row
26694  // after
26695  // validation.
26696  DBCOUNTITEM
26697  ulRowsObtained
26698  = 0;
26699 
26700 DBROWCOUNT
26701  lRow =
26702  m_rgBookmarks
26703  [lBookmarkIndex]
26704  - 1;
26705 // if (((long)*rgpBookmarks[l]) != 0)
26706 // lRow = ((long)*rgpBookmarks[l]) - 1;
26707 
26708  // Attempt to
26709  // create the
26710  // row
26711  if (CreateRow
26712  (lRow,
26713  ulRowsObtained,
26714  &rghRows
26715  [l]) !=
26716  S_OK)
26717  {
26718 
26719 bErrors |=
26720  true;
26721 }
26722 
26723  else
26724 
26725  {
26726 
26727 if
26728  (rgRowStatus
26729  !=
26730  NULL)
26731  rgRowStatus[l]
26732  =
26733  DBROWSTATUS_S_OK;
26734 
26735 
26736 bSuccess |=
26737  true;
26738 }
26739 
26740 }
26741 
26742 
26743 __if_exists
26744  (T::
26745  Fire_OnRowsetChange)
26746 
26747  {
26748 
26749 CAtlArray <
26750  HROW >
26751  rgActivated;
26752 
26753 for (size_t
26754  ulActivated
26755  = 0;
26756  ulActivated
26757  < cRows;
26758  ulActivated++)
26759 
26760  {
26761 
26762  // This is a
26763  // bit of an
26764  // assumption
26765  // that all
26766  // newly
26767  // activated
26768  // rows would
26769  // have the
26770  // ref count
26771  // as 1.
26772  // Another
26773  // way to
26774  // solve
26775  // this
26776  // problem
26777  // would be
26778  // to modify
26779  // the
26780  // signature
26781  // of
26782  // CreateRow
26783  // to take
26784  // a
26785  // CAtlArray<HROW>
26786  // as a
26787  // parameter
26788  // and store
26789  // the
26790  // activated
26791  // rows.
26792  RowClass *
26793  pActiveRow;
26794 
26795 bool bFound =
26796  m_rgRowHandles.
26797  Lookup
26798  (rghRows
26799  [ulActivated],
26800  pActiveRow);
26801 
26802 if (bFound
26803  &&
26804  pActiveRow
26805  != NULL
26806  &&
26807  pActiveRow->
26808  m_dwRef
26809  == 1)
26810  {
26811 
26812 _ATLTRY
26813  {
26814 
26815 rgActivated.
26816  Add (rghRows
26817  [ulActivated]);
26818 
26819 }
26820 
26821 _ATLCATCH (e)
26822 
26823  {
26824 
26825 _ATLDELETEEXCEPTION
26826  (e);
26827 
26828 return
26829  E_OUTOFMEMORY;
26830 
26831 }
26832 
26833 }
26834 
26835 }
26836 
26837 if
26838  (rgActivated.
26839  GetCount () >
26840  0)
26841  {
26842 
26843 pT->
26844  Fire_OnRowChange
26845  (pT,
26846  (DBCOUNTITEM)
26847  rgActivated.
26848  GetCount (),
26849  rgActivated.
26850  GetData (),
26851 
26852 DBREASON_ROW_ACTIVATE,
26853  DBEVENTPHASE_DIDEVENT,
26854  FALSE);
26855 }
26856 
26857 }
26858 
26859 
26860 if (bErrors)
26861 
26862  return
26863  (bSuccess !=
26864  false) ?
26865  DB_S_ERRORSOCCURRED
26866  :
26867  DB_E_ERRORSOCCURRED;
26868 
26869  else
26870 
26871 return hr;
26872 }
26873 
26874 
26875 STDMETHOD (Hash) (HCHAPTER /* hReserved
26876  */
26877  ,
26878  DBBKMARK
26879  cBookmarks,
26880 
26881 const
26882  DBBKMARK
26883  rgcbBookmarks
26884  [],
26885  const
26886  BYTE
26887  *
26888  rgpBookmarks
26889  [],
26890 
26891 DBHASHVALUE
26892  rgHashedValues
26893  [],
26894  DBROWSTATUS
26895  rgBookmarkStatus
26896  [])
26897 
26898  {
26899 
26900 ATLTRACE
26901  (atlTraceDBProvider,
26902  2,
26903  _T
26904  ("IRowsetLocateImpl::Hash\n"));
26905 
26906 
26907 bool
26908  bSuccess =
26909  false;
26910 
26911 bool bErrors
26912  = false;
26913 
26914 
26915 __if_exists
26916  (T::
26917  Fire_OnRowChange)
26918 
26919  {
26920 
26921 T * pT =
26922  (T *) this;
26923  // Check to
26924  // see if
26925  // someone is
26926  // in an
26927  // event
26928  // handler.
26929  // If we do,
26930  // then
26931  // we should
26932  // return
26933  // DB_E_NOTREENTRANT.
26934  if (!pT->
26935  IncrementMutex
26936  ())
26937  return
26938  DB_E_NOTREENTRANT;
26939 
26940  else
26941 
26942 pT->
26943  DecrementMutex
26944  ();
26945 }
26946 
26947 
26948 HRESULT hr =
26949  E_FAIL;
26950  // validate
26951  // parameters
26952  if (cBookmarks
26953  != 0
26954  &&
26955  (rgcbBookmarks
26956  == NULL
26957  ||
26958  rgpBookmarks
26959  == NULL
26960  ||
26961 
26962 rgHashedValues
26963  ==
26964  NULL))
26965  return
26966  E_INVALIDARG;
26967 
26968 
26969  // hash
26970  // values
26971  for (size_t i
26972  = 0;
26973  i <
26974  cBookmarks;
26975  i++)
26976  {
26977 
26978  // Check the
26979  // bookmarks
26980  const BYTE *
26981  pBookmark =
26982  rgpBookmarks
26983  [i];
26984 
26985 hr =
26986  ValidateBookmark
26987  (rgcbBookmarks
26988  [i],
26989  pBookmark);
26990 
26991 if (FAILED
26992  (hr)
26993  ||
26994 
26995  (*pBookmark
26996  ==
26997  DBBMK_LAST
26998  &&
26999  rgcbBookmarks
27000  [i] ==
27001  1)
27002  ||
27003 
27004  (*pBookmark
27005  ==
27006  DBBMK_FIRST
27007  &&
27008  rgcbBookmarks
27009  [i] ==
27010  1))
27011  {
27012 
27013 if
27014  (rgBookmarkStatus
27015  !=
27016  NULL)
27017  rgBookmarkStatus
27018  [i] =
27019  DBROWSTATUS_E_INVALID;
27020 
27021 bErrors |=
27022  true;
27023 
27024 continue;
27025 }
27026 
27027 
27028 rgHashedValues
27029  [i] =
27030  (DBHASHVALUE)
27031  (*
27032  (rgpBookmarks
27033  [i]));
27034 
27035 
27036 if
27037  (rgBookmarkStatus
27038  !=
27039  NULL)
27040  rgBookmarkStatus
27041  [i] =
27042  DBROWSTATUS_S_OK;
27043 
27044 bSuccess |=
27045  true;
27046 
27047 }
27048 
27049 
27050 if (bErrors)
27051 
27052  return
27053  (bSuccess !=
27054  false) ?
27055  DB_S_ERRORSOCCURRED
27056  :
27057  DB_E_ERRORSOCCURRED;
27058 
27059  else
27060 
27061 return S_OK;
27062 }
27063 
27064 
27065  // Data
27066  // members
27067  CAtlArray <
27068  DBROWCOUNT >
27069  m_rgBookmarks;
27070 
27071 
27072  // Implementation
27073  protected:
27074 HRESULT
27075  ValidateBookmark
27076  (DBBKMARK
27077  cbBookmark,
27078  const BYTE *
27079  pBookmark)
27080  {
27081 
27082 T * pT =
27083  (T *) this;
27084 
27085 if
27086  (cbBookmark ==
27087  0
27088  || pBookmark
27089  ==
27090  NULL)
27091  return
27092  E_INVALIDARG;
27093 
27094 
27095  // All of our
27096  // bookmarks
27097  // are
27098  // DBBKMARKs,
27099  // if they
27100  // are
27101  // anything
27102  // other than
27103  //
27104  // sizeof(DBBKMARK)
27105  // then we
27106  // have an
27107  // invalid
27108  // bookmark
27109  if ((cbBookmark != sizeof (DBBKMARK)) && (cbBookmark != 1))
27110  {
27111 
27112 ATLTRACE
27113  (atlTraceDBProvider,
27114  2,
27115  _T
27116  ("Bookmarks are invalid length, should be DBBKMARKs"));
27117 
27118 return
27119  DB_E_BADBOOKMARK;
27120 
27121 }
27122 
27123 
27124  // If our
27125  // bookmark
27126  // is a
27127  // special
27128  // (i.e.
27129  // cbBookmark
27130  // == 1),
27131  // then it
27132  // should
27133  // be one of
27134  // the
27135  // accepted
27136  // values.
27137  if ((cbBookmark == 1) && (*pBookmark != DBBMK_FIRST && *pBookmark != DBBMK_LAST))
27138  {
27139 
27140 ATLTRACE
27141  (atlTraceDBProvider,
27142  2,
27143  _T
27144  ("Bookmark is invalid"));
27145 
27146 return
27147  DB_E_BADBOOKMARK;
27148 
27149 }
27150 
27151 
27152  // If the
27153  // contents
27154  // of our
27155  // bookmarks
27156  // are less
27157  // than 0 or
27158  // greater
27159  // than
27160  // rowcount,
27161  // then they
27162  // are
27163  // invalid
27164  DBCOUNTITEM
27165  nRows =
27166  (ULONG_PTR)
27167  pT->
27168  m_rgBookmarks.
27169  GetCount ();
27170 
27171 DBROWOFFSET
27172  lBookmarkIndex
27173  =
27174  (DBROWOFFSET)
27175  (*pBookmark);
27176 
27177 if
27178  (lBookmarkIndex
27179  <= -1
27180  ||
27181  lBookmarkIndex
27182  >
27183  (DBROWOFFSET)
27184  nRows)
27185  {
27186 
27187 ATLTRACE
27188  (atlTraceDBProvider,
27189  2,
27190  _T
27191  ("IRowsetLocateImpl::Bookmark has invalid range"));
27192 
27193 return
27194  DB_E_BADBOOKMARK;
27195 
27196 }
27197 
27198 
27199 return S_OK;
27200 }
27201 
27202 };
27203 
27204 
27206 // IRowsetIdentityImpl
27207 template < class T, class RowClass = CSimpleRow >
27208 class ATL_NO_VTABLE IRowsetIdentityImpl: public
27209  IRowsetIdentity
27210 
27211  {
27212 
27213 public:
27214 STDMETHOD
27215  (IsSameRow)
27216  (HROW
27217  hThisRow,
27218  HROW
27219  hThatRow)
27220  {
27221 
27222 ATLTRACE
27223  (atlTraceDBProvider,
27224  2,
27225  _T
27226  ("IRowsetIdentityImpl::IsSameRow\n"));
27227 
27228 T * pT =
27229  (T *) this;
27230 
27231  // Validate
27232  // row
27233  // handles
27234  RowClass *
27235  pRow1;
27236 
27237 if (!pT->
27238  m_rgRowHandles.
27239  Lookup ((RowClass::KeyType) hThisRow, pRow1))
27240  return DB_E_BADROWHANDLE;
27241 
27242 RowClass * pRow2;
27243 if (!pT->m_rgRowHandles.Lookup ((RowClass::KeyType) hThatRow, pRow2))
27244  return DB_E_BADROWHANDLE;
27245 
27246 if (pRow1->m_status == DBPENDINGSTATUS_DELETED ||
27247 pRow2->m_status == DBPENDINGSTATUS_DELETED)
27248  return DB_E_DELETEDROW;
27249 
27250 HRESULT hr = pRow1->Compare (pRow2);
27251 __if_not_exists (T::InsertRow)
27252  {
27253 
27254 return hr;
27255 }
27256 
27257 
27258 __if_exists
27259  (T::
27260  InsertRow)
27261  {
27262 
27263 if (hr !=
27264  S_OK)
27265  return hr;
27266 
27267  // Add one
27268  // more test
27269  // for
27270  // providers
27271  // who
27272  // support
27273  // IRowsetChange
27274  // or
27275  // Update.
27276  // It is
27277  // possible
27278  // for a
27279  // series of
27280  // inserts &
27281  // deletes to
27282  // occur to
27283  // make
27284  // CSimpleRow
27285  // appear as
27286  // if it were
27287  // equivalent
27288  // (when it
27289  // is not).
27290  // To
27291  // fix this,
27292  // we've
27293  // added an
27294  // m_iOriginalRowset
27295  // variable
27296  // that never
27297  // gets
27298  // changed.
27299  return
27300  (pRow1->
27301  m_iOriginalRowset
27302  ==
27303  pRow2->
27304  m_iOriginalRowset)
27305  ? S_OK :
27306  S_FALSE;
27307 }
27308 
27309 };
27310 
27311 };
27312 
27313 
27314 template < class T >
27315 class ATL_NO_VTABLE IInternalConnectionImpl: public
27316  IInternalConnection
27317 
27318  {
27319 
27320 public:
27321 STDMETHOD
27322  (AddConnection)
27323  ()
27324  {
27325 
27326 T * pT =
27327  (T *) this;
27328 
27329 T::
27330  _ThreadModel::
27331  Increment
27332  (&pT->
27333  m_cSessionsOpen);
27334 
27335 return S_OK;
27336 
27337 }
27338 
27339 STDMETHOD
27340  (ReleaseConnection)
27341  ()
27342  {
27343 
27344 T * pT =
27345  (T *) this;
27346 
27347 T::
27348  _ThreadModel::
27349  Decrement
27350  (&pT->
27351  m_cSessionsOpen);
27352 
27353 return S_OK;
27354 
27355 }
27356 
27357 };
27358 
27359 
27360 template < class T >
27361 class ATL_NO_VTABLE IInternalCommandConnectionImpl: public
27362  IInternalConnection
27363 
27364  {
27365 
27366 public:
27367 STDMETHOD
27368  (AddConnection)
27369  ()
27370  {
27371 
27372 T * pT =
27373  (T *) this;
27374 
27375 T::
27376  _ThreadModel::
27377  Increment
27378  (&pT->
27379  m_cRowsetsOpen);
27380 
27381 return S_OK;
27382 
27383 }
27384 
27385 STDMETHOD
27386  (ReleaseConnection)
27387  ()
27388  {
27389 
27390 T * pT =
27391  (T *) this;
27392 
27393 T::
27394  _ThreadModel::
27395  Decrement
27396  (&pT->
27397  m_cRowsetsOpen);
27398 
27399 return S_OK;
27400 
27401 }
27402 
27403 };
27404 
27405 
27406 template < class T >
27407 class ATL_NO_VTABLE IObjectWithSiteSessionImpl: public
27408  IObjectWithSiteImpl
27409  < T >
27410  {
27411 
27412 public:
27413 
27415  {
27416 
27417 CComPtr <
27418  IInternalConnection
27419  > pConn;
27420 
27421 if
27422  (m_spUnkSite
27423  != NULL)
27424  {
27425 
27426 if (SUCCEEDED
27427  (m_spUnkSite->
27428  QueryInterface
27429  (__uuidof
27430  (IInternalConnection),
27431  (void
27432  **)
27433  &pConn)))
27434 
27435  pConn->
27436  ReleaseConnection
27437  ();
27438 }
27439 }
27440 
27441 STDMETHOD
27442  (SetSite)
27443  (IUnknown *
27444  pCreator)
27445  {
27446 
27447 HRESULT hr =
27448  S_OK;
27449 
27450 T * pT =
27451  (T *) this;
27452 
27453 pT->Lock ();
27454 
27455 m_spUnkSite =
27456  pCreator;
27457 
27458 pT->
27459  Unlock ();
27460 
27461 CComPtr <
27462  IInternalConnection
27463  > pConn;
27464 
27465 if (pCreator
27466  !=
27467  NULL)
27468  {
27469 
27470 hr =
27471  pCreator->
27472  QueryInterface
27473  (__uuidof
27474  (IInternalConnection),
27475  (void **)
27476  &pConn);
27477 
27478 if (SUCCEEDED
27479  (hr))
27480  hr =
27481  pConn->
27482  AddConnection
27483  ();
27484 }
27485 
27486 return hr;
27487 }
27488 
27489 
27490 LONG
27491  m_cSessionsOpen;
27492 
27493 
27494 };
27495 
27496 
27497 template < class T >
27498 class ATL_NO_VTABLE IRowsetCreatorImpl: public
27499  IObjectWithSiteImpl
27500  < T >
27501  {
27502 
27503 public:
27504 
27506  {
27507 
27508 CComPtr <
27509  IInternalConnection
27510  > pConn;
27511 
27512 if
27513  (m_spUnkSite
27514  != NULL)
27515  {
27516 
27517 if (SUCCEEDED
27518  (m_spUnkSite->
27519  QueryInterface
27520  (__uuidof
27521  (IInternalConnection),
27522  (void
27523  **)
27524  &pConn)))
27525 
27526  pConn->
27527  ReleaseConnection
27528  ();
27529 }
27530 }
27531 
27532 
27533 STDMETHOD
27534  (SetSite)
27535  (IUnknown *
27536  pCreator)
27537  {
27538 
27539 T * pT =
27540  (T *) this;
27541 
27542 HRESULT hr =
27543  S_OK;
27544 
27545 pT->Lock ();
27546 
27547 m_spUnkSite =
27548  pCreator;
27549 
27550 pT->
27551  Unlock ();
27552 
27553 CComVariant
27554  varPropScroll,
27555  varPropFetch,
27556  varPropRemove,
27557  varPropUpdate;
27558 
27559 HRESULT
27560  hrProps =
27561  pT->
27562  GetPropValue
27563  (&DBPROPSET_ROWSET,
27564  DBPROP_CANSCROLLBACKWARDS,
27565  &varPropScroll);
27566 
27567 if (SUCCEEDED
27568  (hrProps))
27569 
27570  pT->
27571  m_bCanScrollBack
27572  =
27573  (varPropScroll.
27574  boolVal !=
27576 
27577 hrProps =
27578  pT->
27579  GetPropValue
27580  (&DBPROPSET_ROWSET,
27581  DBPROP_CANFETCHBACKWARDS,
27582  &varPropFetch);
27583 
27584 if (SUCCEEDED
27585  (hrProps))
27586 
27587  pT->
27588  m_bCanFetchBack
27589  =
27590  (varPropFetch.
27591  boolVal !=
27593 
27594 hrProps =
27595  pT->
27596  GetPropValue
27597  (&DBPROPSET_ROWSET,
27598  DBPROP_REMOVEDELETED,
27599  &varPropRemove);
27600 
27601 if (SUCCEEDED
27602  (hrProps))
27603 
27604  pT->
27605  m_bRemoveDeleted
27606  =
27607  (varPropRemove.
27608  boolVal !=
27610 
27611 hrProps =
27612  pT->
27613  GetPropValue
27614  (&DBPROPSET_ROWSET,
27615  DBPROP_IRowsetUpdate,
27616  &varPropUpdate);
27617 
27618 if (SUCCEEDED
27619  (hrProps))
27620 
27621  pT->
27622  m_bIRowsetUpdate
27623  =
27624  (varPropUpdate.
27625  boolVal !=
27627 
27628 CComPtr <
27629  IInternalConnection
27630  > pConn;
27631 
27632 if (pCreator
27633  !=
27634  NULL)
27635  {
27636 
27637 if (SUCCEEDED
27638  (pCreator->
27639  QueryInterface
27640  (__uuidof
27641  (IInternalConnection),
27642  (void
27643  **)
27644  &pConn)))
27645 
27646  hr =
27647  pConn->
27648  AddConnection
27649  ();
27650 
27651 }
27652 return hr;
27653 
27654 }
27655 
27656 
27657 LONG
27658  m_cRowsetsOpen;
27659 
27660 
27661 };
27662 
27663 
27664 // IRowsetInfoImpl
27665 template < class T, class PropClass = T >
27666 class ATL_NO_VTABLE IRowsetInfoImpl:
27667 public
27668  IRowsetInfo,
27669 
27670 public
27671  CUtlProps <
27672  PropClass >
27673  {
27674 
27675 public:
27676 static
27677  UPROPSET *
27678  _GetPropSet
27679  (ULONG *
27680  pNumPropSets,
27681  ULONG *
27682  pcElemPerSupported,
27683  UPROPSET *
27684  pSet =
27685  NULL,
27686  GUID *
27687  pguidSet =
27688  NULL)
27689  {
27690 
27691 return
27692  PropClass::
27693  _GetPropSet
27694  (pNumPropSets,
27695  pcElemPerSupported,
27696  pSet,
27697  pguidSet);
27698 }
27699 
27700 STDMETHOD
27701  (GetProperties)
27702  (const ULONG
27703  cPropertyIDSets,
27704 
27705 const
27706  DBPROPIDSET
27707  rgPropertyIDSets
27708  [],
27709 
27710 ULONG *
27711  pcPropertySets,
27712 
27713 DBPROPSET **
27714  prgPropertySets)
27715 
27716  {
27717 
27718 ATLTRACE
27719  (atlTraceDBProvider,
27720  2,
27721  _T
27722  ("IRowsetInfoImpl::GetProperties\n"));
27723 
27724 T * pT =
27725  (T *) this;
27726  // Prevent
27727  // Level 4
27728  // warning
27729  pT;
27730 
27731  // IRowsetInfo
27732  // can't
27733  // return
27734  // PROPERTIESINERROR.
27735  // Therefore,
27736  // disable
27737  // checking
27738  // for it.
27739  // Instead,
27740  // treat it
27741  // as any
27742  // normal
27743  // property
27744  // set.
27745  m_dwFlags |=
27747 
27748 HRESULT hr =
27750  (cPropertyIDSets,
27751  rgPropertyIDSets,
27752 
27753 pcPropertySets,
27754  prgPropertySets);
27755 
27756 if (SUCCEEDED
27757  (hr))
27758  {
27759 
27760  // Scan
27761  // property
27762  // sets to
27763  // allow user
27764  // defined
27765  // properies
27766  ULONG ulPropSets = 0;
27767 ULONG ulPropElems = 0;
27768 ULONG ulPropInits = 0;
27769 UPROPSET * pSetA = NULL;
27770 UPROPSET * pSetTemp = NULL;
27771 ULONG l = 0;
27772 ULONG cSets = (ULONG) (ULONG_PTR) pT->_GetPropSet (NULL, &ulPropElems);
27773 
27774 CTempBuffer < UPROPSET > tmpBuffer;
27775 pSetA = tmpBuffer.Allocate (cSets);
27776 if (pSetA == NULL)
27777  return E_OUTOFMEMORY; // We
27778  // shouldn't
27779  // get
27780  // this
27781  // but...
27782  pSetTemp =
27783  pT->
27784  _GetPropSet
27785  (&ulPropSets,
27786  &ulPropElems,
27787  pSetA);
27788 
27789 
27790 typedef
27791  const GUID *
27792  PCGUID;
27793 
27794 
27795 for (l = 0;
27796  l <
27797  cSets;
27798  l++)
27799  {
27800 
27801 if (pSetTemp
27802  [l].
27803  bIsChained
27804  !=
27805  true)
27806  ulPropInits++;
27807 
27808 }
27809 
27810 
27811 CTempBuffer
27812  < PCGUID >
27813  tmpBuffer2;
27814 
27815 PCGUID *
27816  ppGuid =
27817  tmpBuffer2.
27818  Allocate
27819  (ulPropInits);
27820 
27821 if (ppGuid ==
27822  NULL)
27823  return
27824  E_OUTOFMEMORY;
27825 
27826 ulPropInits =
27827  0;
27828 
27829 for (l = 0;
27830  l <
27831  cSets;
27832  l++)
27833  {
27834 
27835 if (pSetTemp
27836  [l].
27837  bIsChained
27838  !=
27839  true)
27840  ppGuid
27841  [ulPropInits++]
27842  =
27843  pSetTemp[l].
27844  pPropSet;
27845 }
27846 
27847 
27848 return
27849  CUtlProps <
27850  PropClass >::
27852  (cPropertyIDSets,
27853 
27854 rgPropertyIDSets,
27855  pcPropertySets,
27856  prgPropertySets,
27857 
27858 ulPropInits,
27859  ppGuid);
27860 }
27861 
27862  else
27863 
27864 return hr;
27865 }
27866 
27867 
27869  ATLCOLUMNINFO
27870  *
27871  InternalGetColumnInfo
27872  (DBORDINAL *
27873  pcCols)
27874  {
27875 
27876 return T::
27877  GetColumnInfo
27878  ((T *) this,
27879  pcCols);
27880 }
27881 
27882 
27883 STDMETHOD
27884  (GetReferencedRowset)
27885  (DBORDINAL
27886  iOrdinal,
27887 
27888 REFIID riid,
27889 
27890 IUnknown **
27891  ppReferencedRowset)
27892 
27893  {
27894 
27895 ATLTRACE
27896  (atlTraceDBProvider,
27897  2,
27898  _T
27899  ("IRowsetInfoImpl::GetReferencedRowset\n"));
27900 
27901 DBORDINAL
27902  cCols = 0;
27903 
27904  // Check
27905  // Arguments
27906  if
27907  (ppReferencedRowset
27908  == NULL)
27909  {
27910 
27911 ATLTRACE
27912  (atlTraceDBProvider,
27913  0,
27914  _T
27915  ("IRowsetInfoImpl::GetReferencedRowset : Error NULL IUnk output Param\n"));
27916 
27917 return
27918  E_INVALIDARG;
27919 
27920 }
27921 
27922 *ppReferencedRowset
27923  = NULL;
27924 
27925  // Check to
27926  // see if
27927  // column in
27928  // question
27929  // is a
27930  // bookmark
27931  ATLCOLUMNINFO
27932  * pColInfo =
27933  InternalGetColumnInfo
27934  (&cCols);
27935 
27936 DBORDINAL
27937  iColInfo;
27938 
27939 for (iColInfo
27940  = 0;
27941 
27942 iColInfo
27943  < cCols
27944  &&
27945  iOrdinal
27946  !=
27947  pColInfo
27948  [iColInfo].
27949  iOrdinal;
27950 
27951 iColInfo++);
27952 
27953 if (iColInfo
27954  ==
27955  cCols)
27956  return
27957  DB_E_BADORDINAL;
27958 
27959 ATLCOLUMNINFO
27960  * pColCur =
27961  &(pColInfo
27962  [iColInfo]);
27963 
27964 
27965 if ((pColCur->dwFlags & DBCOLUMNFLAGS_ISBOOKMARK) == 0)
27966  return DB_E_NOTAREFERENCECOLUMN;
27967 
27968  // Query for
27969  // requested
27970  // interface
27971  return
27972  QueryInterface
27973  (riid,
27974  (void **)
27975  ppReferencedRowset);
27976 
27977 }
27978 
27979 
27980 STDMETHOD
27981  (GetSpecification)
27982  (REFIID riid,
27983 
27984 IUnknown **
27985  ppSpecification)
27986 
27987  {
27988 
27989 ATLTRACE
27990  (atlTraceDBProvider,
27991  2,
27992  _T
27993  ("IRowsetInfoImpl::GetSpecification\n"));
27994 
27995 
27996 if
27997  (ppSpecification
27998  ==
27999  NULL)
28000  return
28001  E_INVALIDARG;
28002 
28003 T * pT =
28004  (T *) this;
28005 
28006 T::
28007  ObjectLock
28008  cab (pT);
28009 
28010 ATLASSERT
28011  (pT->
28012  m_spUnkSite
28013  != NULL);
28014 
28015 return pT->
28016  m_spUnkSite->
28017  QueryInterface
28018  (riid,
28019  (void **)
28020  ppSpecification);
28021 
28022 }
28023 };
28024 
28025 #if 0
28026 template < class Storage, class ContainedArray = CAtlArray < Storage > >
28027 class CUpdateArray: public
28028  ContainedArray
28029 
28030  {
28031 
28032 public:
28033 
28034 void
28035  RemoveAll ()
28036 
28037  {
28038 
28039 ContainedArray::
28040  RemoveAll ();
28041 
28042 m_rgRowLink.
28043  RemoveAll ();
28044 
28045 }
28046 
28047 BOOL
28048  Add (Storage &
28049  rStorage)
28050 
28051  {
28052 
28053 if
28054  (ContainedArray::
28055  Add
28056  (rStorage))
28057  {
28058 
28059 if
28060  (!m_rgRowLink.
28061  Add (GetCount
28062  () -
28063  1))
28064  {
28065 
28066 RemoveAt
28067  (GetCount () -
28068  1);
28069 
28070 return FALSE;
28071 
28072 }
28073 
28074 return TRUE;
28075 }
28076 
28077 return FALSE;
28078 }
28079 
28080 
28081 BOOL
28082  RemoveAt (int
28083  nIndex)
28084 
28085  {
28086 
28087 if
28088  (ContainedArray::
28089  RemoveAt
28090  (m_rgRowLink
28091  [nIndex]))
28092  {
28093 
28094  // Decrement
28095  // any links
28096  // following
28097  // the
28098  // current
28099  // row
28100  for (long l =
28101  nIndex +
28102  1;
28103  l <
28104  m_rgRowLink.
28105  GetCount
28106  ();
28107  l++)
28108  {
28109 
28110 long *pElem =
28111  &(m_rgRowLink.
28112  m_aT[l]);
28113 
28114 ATLASSERT
28115  (pElem !=
28116  NULL);
28117 
28118 (*pElem)--;
28119 
28120 }
28121 return
28122  m_rgRowLink.
28123  RemoveAt
28124  (nIndex);
28125 }
28126 
28127 return FALSE;
28128 }
28129 
28130 
28131 ContainedArray::
28132  _ArrayElementType
28133  &
28134  operator[](int
28135  nIndex)
28136 
28137  {
28138 
28139 ATLASSERT
28140  (nIndex >= 0
28141  && nIndex <
28142  GetCount ());
28143 
28144 return
28145  ContainedArray::
28146  operator[]
28147  (m_rgRowLink
28148  [nIndex]);
28149 }
28150 
28151 
28152 const
28153  ContainedArray::
28154  _ArrayElementType
28155  &
28156  operator[](int
28157  nIndex)
28158  const
28159  {
28160 
28161 ATLASSERT
28162  (nIndex >= 0
28163  && nIndex <
28164  GetCount ());
28165 
28166 return
28167  ContainedArray::
28168  operator[]
28169  (m_rgRowLink
28170  [nIndex]);
28171 }
28172 
28173 
28174 CSimpleValArray
28175  <
28176  long
28177  >m_rgRowLink;
28178 
28179 };
28180 #endif /*
28181  */
28182 
28183 class
28185 
28186  {
28187 
28188 public:
28190  {
28191 
28192 m_lInterlockedVariable
28193  = -1;
28194 };
28195 
28196 
28197 inline bool
28198  IncrementMutex
28199  ()
28200  {
28201 
28202 long
28203  lAvailable =::
28204  InterlockedIncrement
28205  (&m_lInterlockedVariable);
28206 
28207 if
28208  (lAvailable >
28209  0)
28210  {
28211 
28212  // Mutex is
28213  // held,
28214  // decrement
28215  // and return
28216  // false
28217  DecrementMutex
28218  ();
28219 
28220 return false;
28221 
28222 }
28223 
28224  else
28225 
28226 return true;
28227 
28228 };
28229 
28230 inline void
28231  DecrementMutex
28232  ()
28233  {
28234 
28235 ::InterlockedDecrement (&m_lInterlockedVariable);
28236 };
28237 
28238 long m_lInterlockedVariable;
28239 };
28240 
28241 
28242 template < class T, class ReentrantEventSync = CComSharedMutex >
28243 class IRowsetNotifyCP:public
28244  IConnectionPointImpl
28245  < T,
28246  &__uuidof
28247  (IRowsetNotify),
28248  CComDynamicUnkArray
28249  >,
28250 
28251 public
28252  ReentrantEventSync
28253 
28254  {
28255 
28256 public:
28257 HRESULT
28259  (IRowset *
28260  pRowset,
28261  HROW hRow,
28262  DBORDINAL
28263  cColumns,
28264 
28265 DBORDINAL *
28266  rgColumns,
28267  DBREASON
28268  eReason,
28269  DBEVENTPHASE
28270  ePhase,
28271 
28272 BOOL
28273  fCantDeny)
28274  {
28275 
28276 ATLTRACE (atlTraceDBProvider, 2, _T ("IRowsetNotifyCP::Fire_OnFieldChange\n"));
28277 
28278 IncrementMutex (); // Lock
28279  // the
28280  // event
28281  // handler
28282  // so
28283  // other's
28284  // can't
28285  // call
28286  // methods
28287  HRESULT ret =
28288  S_OK;
28289 
28290 T * pT =
28291  static_cast <
28292  T * >(this);
28293 
28294 int
28295  nConnectionIndex;
28296 
28297 int
28298  nConnections =
28299  m_vec.
28300  GetSize ();
28301 
28302 
28303 for
28304  (nConnectionIndex
28305  = 0;
28306  nConnectionIndex
28307  <
28308  nConnections;
28309  nConnectionIndex++)
28310 
28311  {
28312 
28313 pT->Lock ();
28314 
28315 CComPtr <
28316  IUnknown >
28317  sp =
28318  m_vec.
28319  GetAt
28320  (nConnectionIndex);
28321 
28322 pT->
28323  Unlock ();
28324 
28325 IRowsetNotify
28326  *
28327  pIRowsetNotify
28328  =
28329  reinterpret_cast
28330  <
28331  IRowsetNotify
28332  * >(sp.p);
28333 
28334 if
28335  (pIRowsetNotify
28336  !=
28337  NULL)
28338  ret =
28339  pIRowsetNotify->
28340  OnFieldChange
28341  (pRowset,
28342  hRow,
28343  cColumns,
28344 
28345 rgColumns,
28346  eReason,
28347  ePhase,
28348  fCantDeny);
28349 
28350 switch
28351  (ePhase)
28352  {
28353 
28354 case DBEVENTPHASE_OKTODO:
28355 
28356 if (ret ==
28357  S_FALSE
28358  &&
28359  fCantDeny
28360  ==
28361  FALSE)
28362  {
28363 
28364  // if we get
28365  // an S_FALSE
28366  // back, a
28367  // consumer
28368  // has vetoed
28369  // the
28370  // request.
28371  // In this
28372  // case, we
28373  // should
28374  // send a
28375  // FAILEDTODO
28376  // to ONLY
28377  // those
28378  // consumers
28379  // already
28380  // notified.
28381  for (int
28382  nFailedIndex
28383  = 0;
28384  nFailedIndex
28385  <=
28386  nConnectionIndex;
28387  nFailedIndex++)
28388 
28389  {
28390 
28391 pT->Lock ();
28392 
28393 CComPtr <
28394  IUnknown >
28395  sp =
28396  m_vec.
28397  GetAt
28398  (nFailedIndex);
28399 
28400 pT->
28401  Unlock ();
28402 
28403 IRowsetNotify
28404  *
28405  pIFailedNotify
28406  =
28407  reinterpret_cast
28408  <
28409  IRowsetNotify
28410  * >(sp.p);
28411 
28412 if
28413  (pIFailedNotify
28414  !=
28415  NULL)
28416  pIFailedNotify->
28417  OnFieldChange
28418  (pRowset,
28419  hRow,
28420  cColumns,
28421  rgColumns,
28422 
28423 eReason,
28424  DBEVENTPHASE_FAILEDTODO,
28425  FALSE);
28426 }
28427 
28428  // Terminate
28429  // the loop
28430  // as no
28431  // further
28432  // consumers
28433  // should be
28434  // notified.
28435  DecrementMutex
28436  ();
28437 
28438 return ret;
28439 
28440 }
28441 
28442  else
28443 
28444  {
28445 
28446 if (ret !=
28447  S_OK)
28448  ret = S_OK;
28449 }
28450 
28451 break;
28452 case DBEVENTPHASE_ABOUTTODO:
28453 
28454 case DBEVENTPHASE_SYNCHAFTER:
28455 
28456 if (ret ==
28457  S_FALSE
28458  &&
28459  fCantDeny
28460  ==
28461  FALSE)
28462  {
28463 
28465  (pRowset,
28466  hRow,
28467  cColumns,
28468  rgColumns,
28469 
28470 eReason,
28471  DBEVENTPHASE_FAILEDTODO,
28472  FALSE);
28473 
28474 DecrementMutex
28475  ();
28476 
28477 return ret;
28478 
28479 }
28480 
28481  else
28482 
28483  {
28484 
28485 if (ret !=
28486  S_OK)
28487  ret = S_OK;
28488 }
28489 
28490 break;
28491 case DBEVENTPHASE_FAILEDTODO:
28492 
28493 case DBEVENTPHASE_DIDEVENT:
28494 
28495 break; // Nothing
28496  // todo
28497 default:
28498 
28499 ATLTRACE
28500  (atlTraceDBProvider,
28501  0,
28502  _T
28503  ("IRowsetNotifyCP::Fire_OnFieldChange: Unknown Phase requested\n"));
28504 
28505 ATLASSERT
28506  (FALSE);
28507 
28508 DecrementMutex
28509  ();
28510 
28511 return
28512  E_FAIL;
28513 };
28514 
28515 }
28516 
28517 DecrementMutex
28518  ();
28519 
28520 if (ret !=
28521  S_OK
28522  && ret !=
28523  S_FALSE)
28524 
28525  ret = S_OK;
28526 
28527 return ret;
28528 
28529 
28530 }
28531 
28532 HRESULT
28534  (IRowset *
28535  pRowset,
28536  DBCOUNTITEM
28537  cRows,
28538  const HROW
28539  rghRows[],
28540 
28541 DBREASON
28542  eReason,
28543  DBEVENTPHASE
28544  ePhase,
28545  BOOL
28546  fCantDeny)
28547  {
28548 
28549 ATLTRACE (atlTraceDBProvider, 2, _T ("IRowsetNotifyCP::Fire_OnRowChange\n"));
28550 IncrementMutex (); // Lock
28551  // the
28552  // handler
28553  // so
28554  // other's
28555  // can't
28556  // call
28557  // methods
28558  HRESULT ret =
28559  S_OK;
28560 
28561 T * pT =
28562  static_cast <
28563  T * >(this);
28564 
28565 int
28566  nConnectionIndex;
28567 
28568 int
28569  nConnections =
28570  m_vec.
28571  GetSize ();
28572 
28573 
28574 for
28575  (nConnectionIndex
28576  = 0;
28577  nConnectionIndex
28578  <
28579  nConnections;
28580  nConnectionIndex++)
28581 
28582  {
28583 
28584 pT->Lock ();
28585 
28586 CComPtr <
28587  IUnknown >
28588  sp =
28589  m_vec.
28590  GetAt
28591  (nConnectionIndex);
28592 
28593 pT->
28594  Unlock ();
28595 
28596 IRowsetNotify
28597  *
28598  pIRowsetNotify
28599  =
28600  reinterpret_cast
28601  <
28602  IRowsetNotify
28603  * >(sp.p);
28604 
28605 if
28606  (pIRowsetNotify
28607  != NULL)
28608  {
28609 
28610 ret =
28611  pIRowsetNotify->
28612  OnRowChange
28613  (pRowset,
28614  cRows,
28615  rghRows,
28616  eReason,
28617  ePhase,
28618  fCantDeny);
28619 
28620 }
28621 
28622 switch
28623  (ePhase)
28624  {
28625 
28626 case DBEVENTPHASE_OKTODO:
28627 
28628 if (ret ==
28629  S_FALSE
28630  &&
28631  fCantDeny
28632  ==
28633  FALSE)
28634  {
28635 
28636  // if we get
28637  // an S_FALSE
28638  // back, a
28639  // consumer
28640  // has vetoed
28641  // the
28642  // request.
28643  // In this
28644  // case, we
28645  // should
28646  // send a
28647  // FAILEDTODO
28648  // to ONLY
28649  // those
28650  // consumers
28651  // already
28652  // notified.
28653  for (int
28654  nFailedIndex
28655  = 0;
28656  nFailedIndex
28657  <=
28658  nConnectionIndex;
28659  nFailedIndex++)
28660 
28661  {
28662 
28663 pT->Lock ();
28664 
28665 CComPtr <
28666  IUnknown >
28667  sp =
28668  m_vec.
28669  GetAt
28670  (nFailedIndex);
28671 
28672 pT->
28673  Unlock ();
28674 
28675 IRowsetNotify
28676  *
28677  pIFailedNotify
28678  =
28679  reinterpret_cast
28680  <
28681  IRowsetNotify
28682  * >(sp.p);
28683 
28684 if
28685  (pIFailedNotify
28686  !=
28687  NULL)
28688  pIFailedNotify->
28689  OnRowChange
28690  (pRowset,
28691  cRows,
28692  rghRows,
28693  eReason,
28694 
28695 DBEVENTPHASE_FAILEDTODO,
28696  FALSE);
28697 }
28698 
28699  // Terminate
28700  // the loop
28701  // as no
28702  // further
28703  // consumers
28704  // should be
28705  // notified.
28706  DecrementMutex
28707  ();
28708 
28709 return ret;
28710 
28711 }
28712 
28713 break;
28714 case DBEVENTPHASE_SYNCHAFTER:
28715 
28716 case DBEVENTPHASE_ABOUTTODO:
28717 
28718 if (ret ==
28719  S_FALSE
28720  &&
28721  fCantDeny
28722  ==
28723  FALSE)
28724  {
28725 
28727  (pRowset,
28728  cRows,
28729  rghRows,
28730  eReason,
28731 
28732 DBEVENTPHASE_FAILEDTODO,
28733  FALSE);
28734 
28735 DecrementMutex
28736  ();
28737 
28738 return ret;
28739 
28740 }
28741 
28742 break;
28743 case DBEVENTPHASE_FAILEDTODO:
28744 
28745 case DBEVENTPHASE_DIDEVENT:
28746 
28747 break; // Nothing
28748  // todo
28749 default:
28750 
28751 ATLTRACE
28752  (atlTraceDBProvider,
28753  0,
28754  _T
28755  ("IRowsetNotifyCP::Fire_OnRowChange: Unknown Phase requested\n"));
28756 
28757 ATLASSERT
28758  (FALSE);
28759 
28760 DecrementMutex
28761  ();
28762 
28763 return
28764  E_FAIL;
28765 };
28766 
28767 }
28768 
28769 DecrementMutex
28770  ();
28771 
28772 if (ret !=
28773  S_OK
28774  && ret !=
28775  S_FALSE)
28776 
28777  ret = S_OK;
28778 
28779 return ret;
28780 
28781 
28782 }
28783 
28784 HRESULT
28786  (IRowset *
28787  pRowset,
28788  DBREASON
28789  eReason,
28790 
28791 DBEVENTPHASE
28792  ePhase,
28793  BOOL
28794  fCantDeny)
28795  {
28796 
28797 ATLTRACE (atlTraceDBProvider, 2, _T ("IRowsetNotifyCP::Fire_OnRowsetChange\n"));
28798 IncrementMutex (); // Lock
28799  // the
28800  // handler
28801  // so
28802  // others
28803  // can't
28804  // call
28805  // methods
28806  HRESULT ret =
28807  S_OK;
28808 
28809 T * pT =
28810  static_cast <
28811  T * >(this);
28812 
28813 int
28814  nConnectionIndex;
28815 
28816 int
28817  nConnections =
28818  m_vec.
28819  GetSize ();
28820 
28821 
28822 for
28823  (nConnectionIndex
28824  = 0;
28825  nConnectionIndex
28826  <
28827  nConnections;
28828  nConnectionIndex++)
28829 
28830  {
28831 
28832 pT->Lock ();
28833 
28834 CComPtr <
28835  IUnknown >
28836  sp =
28837  m_vec.
28838  GetAt
28839  (nConnectionIndex);
28840 
28841 pT->
28842  Unlock ();
28843 
28844 IRowsetNotify
28845  *
28846  pIRowsetNotify
28847  =
28848  reinterpret_cast
28849  <
28850  IRowsetNotify
28851  * >(sp.p);
28852 
28853 if
28854  (pIRowsetNotify
28855  !=
28856  NULL)
28857  ret =
28858  pIRowsetNotify->
28859  OnRowsetChange
28860  (pRowset,
28861  eReason,
28862  ePhase,
28863  fCantDeny);
28864 
28865 switch
28866  (ePhase)
28867  {
28868 
28869 case DBEVENTPHASE_OKTODO:
28870 
28871 if (ret ==
28872  S_FALSE
28873  &&
28874  fCantDeny
28875  ==
28876  FALSE)
28877  {
28878 
28879  // if we get
28880  // an S_FALSE
28881  // back, a
28882  // consumer
28883  // has vetoed
28884  // the
28885  // request.
28886  // In this
28887  // case, we
28888  // should
28889  // send a
28890  // FAILEDTODO
28891  // to ONLY
28892  // those
28893  // consumers
28894  // already
28895  // notified.
28896  for (int
28897  nFailedIndex
28898  = 0;
28899  nFailedIndex
28900  <=
28901  nConnectionIndex;
28902  nFailedIndex++)
28903 
28904  {
28905 
28906 pT->Lock ();
28907 
28908 CComPtr <
28909  IUnknown >
28910  sp =
28911  m_vec.
28912  GetAt
28913  (nFailedIndex);
28914 
28915 pT->
28916  Unlock ();
28917 
28918 IRowsetNotify
28919  *
28920  pIFailedNotify
28921  =
28922  reinterpret_cast
28923  <
28924  IRowsetNotify
28925  * >(sp.p);
28926 
28927 if
28928  (pIFailedNotify
28929  !=
28930  NULL)
28931  pIFailedNotify->
28932  OnRowsetChange
28933  (pRowset,
28934  eReason,
28935 
28936 DBEVENTPHASE_FAILEDTODO,
28937  FALSE);
28938 }
28939 
28940  // Terminate
28941  // the loop
28942  // as no
28943  // further
28944  // consumers
28945  // should be
28946  // notified.
28947  //
28948  DecrementMutex
28949  ();
28950 
28951 return ret;
28952 
28953 }
28954 
28955 break;
28956 case DBEVENTPHASE_ABOUTTODO:
28957 
28958 case DBEVENTPHASE_SYNCHAFTER:
28959 
28960 if (ret ==
28961  S_FALSE
28962  &&
28963  fCantDeny
28964  ==
28965  FALSE)
28966  {
28967 
28969  (pRowset,
28970  eReason,
28971  DBEVENTPHASE_FAILEDTODO,
28972 
28973 FALSE);
28974 
28975 DecrementMutex
28976  ();
28977 
28978 return ret;
28979 
28980 }
28981 
28982 break;
28983 case DBEVENTPHASE_FAILEDTODO:
28984 
28985 case DBEVENTPHASE_DIDEVENT:
28986 
28987 break; // Nothing
28988  // todo
28989 default:
28990 
28991 ATLTRACE
28992  (atlTraceDBProvider,
28993  0,
28994  _T
28995  ("IRowsetNotifyCP::Fire_OnRowChange: Unknown Phase requested\n"));
28996 
28997 ATLASSERT
28998  (FALSE);
28999 
29000 DecrementMutex
29001  ();
29002 
29003 return
29004  E_FAIL;
29005 };
29006 
29007 }
29008 
29009 DecrementMutex
29010  ();
29011 
29012 if (ret !=
29013  S_OK
29014  && ret !=
29015  S_FALSE)
29016 
29017  ret = S_OK;
29018 
29019 return ret;
29020 
29021 
29022 }
29023 
29024 };
29025 
29026 
29027 
29028 template < class T, class Storage,
29029 class ArrayType = CAtlArray < Storage >,
29030 class RowsetInterface = IRowsetImpl < T, IRowset > >
29031 class CRowsetBaseImpl:
29032 public
29034  < T >,
29035 
29036 public
29038  < T >,
29039 
29040 public
29042  < T >,
29043 
29044 public
29046  < T >,
29047 
29048 public
29050  < T >,
29051 
29052 public
29053  RowsetInterface
29054 
29055  {
29056 
29057 public:
29058 HRESULT
29059  NameFromDBID
29060  (DBID * pDBID,
29061  CComBSTR &
29062  bstr,
29063  bool bIndex)
29064 
29065  {
29066 
29067 
29068 if (pDBID->
29069  uName.
29070  pwszName
29071  !=
29072  NULL)
29073  {
29074 
29075 bstr =
29076  pDBID->uName.
29077  pwszName;
29078 
29079 if (bstr ==
29080  (BSTR)
29081  NULL)
29082  return
29083  E_OUTOFMEMORY;
29084 
29085 return S_OK;
29086 
29087 }
29088 
29089 
29090 return
29091  (bIndex) ?
29092  DB_E_NOINDEX :
29093  DB_E_NOTABLE;
29094 
29095 }
29096 
29097 
29098 HRESULT
29100  (DBID *
29101  pTableID,
29102  DBID *
29103  pIndexID)
29104  {
29105 
29106 USES_CONVERSION;
29107 
29108 HRESULT hr;
29109 
29110 
29111 if (pTableID
29112  == NULL
29113  &&
29114  pIndexID
29115  ==
29116  NULL)
29117  return
29118  E_INVALIDARG;
29119 
29120 
29121 if (pTableID
29122  != NULL
29123  &&
29124  pTableID->
29125  eKind ==
29126  DBKIND_NAME)
29127 
29128  {
29129 
29130 hr =
29131  NameFromDBID
29132  (pTableID,
29134  true);
29135 
29136 if (FAILED
29137  (hr))
29138  return hr;
29139 
29140 if (pIndexID
29141  !=
29142  NULL)
29143  {
29144 
29145 if
29146  (pIndexID->
29147  eKind ==
29148  DBKIND_NAME)
29149 
29150  {
29151 
29152 hr =
29153  NameFromDBID
29154  (pIndexID,
29156  false);
29157 
29158 if (FAILED
29159  (hr))
29160  {
29161 
29163  Empty ();
29164 
29165 return hr;
29166 }
29167 
29168 }
29169 
29170  else
29171 
29172  {
29173 
29175  Empty ();
29176 
29177 return
29178  DB_E_NOINDEX;
29179 
29180 }
29181 
29182 }
29183 
29184 return S_OK;
29185 }
29186 
29187 if (pIndexID
29188  != NULL
29189  &&
29190  pIndexID->
29191  eKind ==
29192  DBKIND_NAME)
29193 
29194  return
29195  NameFromDBID
29196  (pIndexID,
29198  false);
29199 
29200 
29201 return S_OK;
29202 
29203 }
29204 
29205 
29206 HRESULT
29208  (DBID *
29209  pTableID,
29210  DBID *
29211  pIndexID)
29212  {
29213 
29214 HRESULT hr =
29215  S_OK;
29216 
29217 
29218 if (pTableID
29219  !=
29220  NULL)
29221  {
29222 
29223 hr =
29224  CUtlProps <
29225  T >::
29226  IsValidDBID
29227  (pTableID);
29228 
29229 
29230 if (hr !=
29231  S_OK)
29232  return hr;
29233 
29234  // Check for
29235  // a NULL
29236  // TABLE ID
29237  // (where its
29238  // a valid
29239  // pointer
29240  // but NULL)
29241  if ((pTableID->eKind == DBKIND_GUID_NAME ||
29242 pTableID->eKind == DBKIND_NAME ||
29243 pTableID->eKind == DBKIND_PGUID_NAME)
29244  &&pTableID->uName.pwszName == NULL)
29245  return DB_E_NOTABLE;
29246 }
29247 
29248 
29249 if (pIndexID
29250  !=
29251  NULL)
29252  hr =
29253  CUtlProps <
29254  T >::
29255  IsValidDBID
29256  (pIndexID);
29257 
29258 
29259 return hr;
29260 
29261 }
29262 
29263 
29264 HRESULT
29266  (DBID *
29267  pTableID,
29268  DBID *
29269  pIndexID)
29270  {
29271 
29272 T * pT =
29273  (T *) this;
29274 
29275 HRESULT hr =
29276  pT->
29278  (pTableID,
29279  pIndexID);
29280 
29281 if (FAILED
29282  (hr))
29283  return hr;
29284 
29285 hr =
29286  pT->
29288  (pTableID,
29289  pIndexID);
29290 
29291 return hr;
29292 }
29293 
29294 
29295 static
29296  ATLCOLUMNINFO
29297  *
29299  (T * pv,
29300  DBORDINAL *
29301  pcCols)
29302  {
29303 
29304 return
29305  Storage::
29306  GetColumnInfo
29307  (pv, pcCols);
29308 
29309 }
29310 
29311 
29312 CComBSTR
29314 
29315 CComBSTR
29317 
29318 
29319 ArrayType
29320  m_rgRowData;
29321 
29322 };
29323 
29324 
29325 
29326 template < class T, class Storage, class CreatorClass,
29327 class ArrayType = CAtlArray < Storage >,
29328 class RowClass = CSimpleRow,
29329 class RowsetInterface = IRowsetImpl < T, IRowset > >
29330 class CRowsetImpl:
29331 public
29332  CComObjectRootEx
29333  <
29334  CreatorClass::
29335  _ThreadModel
29336  >,
29337 
29338 public
29340  < T, Storage,
29341  ArrayType,
29342  RowsetInterface
29343  >,
29344 
29345 public
29347  < T,
29348  CreatorClass::
29349  _PropClass >
29350  {
29351 
29352 public:
29353 typedef
29354  CRowsetImpl <
29355  T, Storage,
29356  CreatorClass,
29357  ArrayType,
29358  RowClass,
29359  RowsetInterface
29360  >
29362 
29363 typedef
29364  ArrayType
29366 
29367 typedef
29368  Storage
29370 
29371 typedef
29372  CreatorClass
29374 
29375 
29378 
29379  COM_INTERFACE_ENTRY
29380  (IRowsetInfo)
29381 
29382  COM_INTERFACE_ENTRY
29383  (IAccessor)
29384  COM_INTERFACE_ENTRY
29385  (IObjectWithSite)
29386 
29387  COM_INTERFACE_ENTRY
29388  (IColumnsInfo)
29389 
29390  COM_INTERFACE_ENTRY
29391  (IConvertType)
29392 
29393  COM_INTERFACE_ENTRY
29394  (IRowsetIdentity)
29395 
29396  COM_INTERFACE_ENTRY
29397  (IRowset)
29398  END_COM_MAP ()
29399 
29400 
29401 HRESULT
29403  ()
29404  {
29405 
29406 HRESULT hr =
29408  <
29409  T >::
29411  ();
29412 
29413 if (FAILED
29414  (hr))
29415  return hr;
29416 
29417 return
29420  ();
29421 }
29422 
29423 
29424 void
29425  FinalRelease
29426  ()
29427  {
29428 
29429 m_rgRowData.
29430  RemoveAll ();
29431 
29433  <
29434  T >::
29436  ();
29437 
29438 __if_exists
29439  (T::
29440  Fire_OnRowsetChange)
29441 
29442  {
29443 
29444 T * pT = (T *) this;
29445 pT->Fire_OnRowsetChange (pT, DBREASON_ROWSET_RELEASE, DBEVENTPHASE_DIDEVENT, TRUE);
29446 }
29447 }
29448 };
29449 
29450 
29451 template < class T, class Storage, class CreatorClass,
29452 class ArrayType = CAtlArray < Storage >,
29453 class RowClass = CSimpleRow,
29454 class RowsetInterface = IRowsetImpl < T, IRowset > >
29455 class CSchemaRowsetImpl:
29456 public
29457  CComObjectRootEx
29458  <
29459  CreatorClass::
29460  _ThreadModel
29461  >,
29462 
29463 public
29465  < T, Storage,
29466  ArrayType,
29467  RowsetInterface
29468  >,
29469 
29470 public
29472  < T >
29473  {
29474 
29475 public:
29476 typedef
29478  < T, Storage,
29479  CreatorClass,
29480  ArrayType,
29481  RowClass,
29482  RowsetInterface
29483  >
29485 
29486 typedef
29487  ArrayType
29489 
29490 typedef
29491  Storage
29493 
29494 typedef
29495  CreatorClass
29497 
29498 
29501 
29502  COM_INTERFACE_ENTRY
29503  (IRowsetInfo)
29504 
29505  COM_INTERFACE_ENTRY
29506  (IAccessor)
29507  COM_INTERFACE_ENTRY
29508  (IObjectWithSite)
29509 
29510  COM_INTERFACE_ENTRY
29511  (IColumnsInfo)
29512 
29513  COM_INTERFACE_ENTRY
29514  (IConvertType)
29515 
29516  COM_INTERFACE_ENTRY
29517  (IRowsetIdentity)
29518 
29519  COM_INTERFACE_ENTRY
29520  (IRowset)
29521  END_COM_MAP ()
29522 
29523 
29524 HRESULT
29526  ()
29527  {
29528 
29529 HRESULT hr =
29531  <
29532  T >::
29534  ();
29535 
29536 if (FAILED
29537  (hr))
29538  return hr;
29539 
29540 return
29543  ();
29544 }
29545 
29546 
29547 void
29548  FinalRelease
29549  ()
29550  {
29551 
29552 m_rgRowData.
29553  RemoveAll ();
29554 
29555 __if_exists
29556  (T::
29557  Fire_OnRowsetChange)
29558 
29559  {
29560 
29561 T * pT =
29562  (T *) this;
29563 
29564 pT->
29565  Fire_OnRowsetChange
29566  (pT,
29567  DBREASON_ROWSET_RELEASE,
29568  DBEVENTPHASE_DIDEVENT,
29569  TRUE);
29570 
29571 }
29572 }
29573 };
29574 
29575 
29576 
29577 template <
29578  const GUID *
29579  pguidProvider
29580  >
29581 
29582 class
29584 
29585  {
29586 
29587 public:
29588 
29589 HRESULT
29590  PostError
29591  (HRESULT
29592  hrErr,
29593  IID * piid)
29594  {
29595 
29596 HRESULT hr =
29597  S_OK;
29598 
29599 if (piid ==
29600  NULL)
29601  return
29602  E_INVALIDARG;
29603 
29604 
29605 CComPtr <
29606  ICreateErrorInfo
29607  >
29608  spCrtErrInfo;
29609 
29610 CComPtr <
29611  IErrorInfo >
29612  spIErrorInfo;
29613 
29614 CComPtr <
29615  IErrorRecords
29616  >
29617  spIErrorRecords;
29618 
29619 
29620 hr =
29621  CreateErrorInfo
29622  (&spCrtErrInfo);
29623 
29624 if (SUCCEEDED
29625  (hr))
29626  {
29627 
29628 ERRORINFO
29629  errorinfo;
29630 
29631 memset
29632  (&errorinfo,
29633  0,
29634  sizeof
29635  (ERRORINFO));
29636 
29637 errorinfo.
29638  clsid =
29639  *pguidProvider;
29640 
29641 errorinfo.
29642  dispid = NULL;
29643 
29644 errorinfo.
29645  dwMinor = 0;
29646 
29647 errorinfo.
29648  hrError =
29649  hrErr;
29650 
29651 errorinfo.
29652  iid = *piid;
29653 
29654 
29655 spCrtErrInfo->
29656  SetGUID
29657  (errorinfo.
29658  iid)
29659  spCrtErrInfo->
29660  SetSource
29661  (OLESTR
29662  ("Provider PROGID"));
29663 
29664 spCrtErrInfo->
29665  SetDescription
29666  (OLESTR
29667  ("Error Description"));
29668 
29669 spCrtErrInfo->
29670  SetHelpFile
29671  (OLESTR
29672  ("provider.hlp"));
29673 
29674 spCrtErrInfo->
29675  SetHelpContext
29676  (1);
29677 
29678  // Obtain the
29679  // error
29680  // object or
29681  // create a
29682  // new one if
29683  // none
29684  // exists
29685  GetErrorInfo
29686  (0,
29687  &spIErrorInfo);
29688 
29689 if
29690  (spIErrorInfo
29691  == NULL)
29692  {
29693 
29694 hr =
29695  spIErrorInfo->
29696  CoCreateInstance
29697  (CLSID_EXTENDEDERRORINFO);
29698 
29699 if (FAILED
29700  (hr))
29701  return hr;
29702 }
29703 
29704 
29705  // Obtain the
29706  // IErrorRecord
29707  // Interface
29708  hr =
29709  spIErrorInfo->
29710  QueryInterface
29711  (__uuidof
29712  (IErrorRecords),
29713  &spIErrorRecords));
29714 
29715 if (SUCCEEDED (hr))
29716 
29717  {
29718 
29719 hr =
29720  spIErrorRecords->
29721  AddErrorRecord
29722  (&errorinfo, 0, NULL,
29723  &spICrtErrInfo, 0);
29724 
29725 if (FAILED (hr))
29726  return hr;
29727 }
29728 
29729 }
29730 
29731 
29732 if (spIErrorInfo !=
29733  NULL)
29734  SetErrorInfo (0,
29735  &spIErrorInfo);
29736 
29737 
29738 return hr;
29739 }
29740 
29741 
29742 
29743 };
29744 
29745 
29746 struct ATLERRORINFO
29747 
29748  {
29749 
29750 ERRORINFO * pInfo;
29751 DISPPARAMS dispparams;
29752 CComPtr < IUnknown > spCustError;
29753 DWORD dwLookupID;
29754 
29755 };
29756 
29757 template < class T, class RecordClass = ATLERRORINFO >
29758 class IErrorRecordsImpl:public IErrorRecords
29759 
29760  {
29761 
29762 public:
29763 STDMETHOD
29764  (AddErrorRecord)
29765  (ERRORINFO *
29766  pErrorInfo,
29767  DWORD dwLookupID,
29768  DISPPARAMS *
29769  pdispparams,
29770  IUnknown *
29771  punkCustomError,
29772  DWORD)
29773  {
29774 
29775 ATLTRACE
29776  (atlTraceDBProvider,
29777  2,
29778  _T
29779  ("IErrorRecordsImpl::AddErrorRecord\n"));
29780 
29781 if (pErrorInfo ==
29782  NULL)
29783  return
29784  E_INVALIDARG;
29785 
29787 
29788 
29789 err.pInfo =
29790  pErrorInfo;
29791 
29792 err.dispparams =
29793  *pdispparams;
29794 
29795 err.spCustError =
29796  punkCustomError;
29797 
29798 err.dwLookupID =
29799  dwLookupID;
29800 
29801  // if
29802  // (!m_rgErrors.Add(err))
29803  //
29804  // return
29805  // E_OUTOFMEMORY;
29806  _ATLTRY
29807  {
29808 
29809 m_rgErrors.
29810  Add (err);
29811 }
29812 
29813 _ATLCATCH (e)
29814  {
29815 
29816 _ATLDELETEEXCEPTION
29817  (e);
29818 
29819 return
29820  E_OUTOFMEMORY;
29821 }
29822 
29823 
29824 return S_OK;
29825 }
29826 
29827 
29828 STDMETHOD
29830  (ULONG ulRecordNum,
29831  ERRORINFO *
29832  pErrorInfo)
29833  {
29834 
29835 ATLTRACE
29836  (atlTraceDBProvider,
29837  2,
29838  _T
29839  ("IErrorRecordsImpl::GetBasicErrorInfo\n"));
29840 
29841 if (pErrorInfo ==
29842  NULL)
29843  return
29844  E_INVALIDARG;
29845 
29846 if ((LONG)
29847  ulRecordNum >=
29848  m_rgErrors.
29849  GetCount ())
29850  return
29851  DB_E_BADRECORDNUM;
29852 
29853 
29854 *pErrorInfo =
29855  *(m_rgErrors
29856  [ulRecordNum].
29857  pInfo);
29858 
29859 return S_OK;
29860 }
29861 
29862 
29863 STDMETHOD
29865  (ULONG ulRecordNum,
29866  REFIID riid,
29867  IUnknown **
29868  ppObject)
29869  {
29870 
29871 ATLTRACE
29872  (atlTraceDBProvider,
29873  2,
29874  _T
29875  ("IErrorRecordsImpl::GetCustomErrorObject\n"));
29876 
29877 if (ppObject ==
29878  NULL)
29879  return
29880  E_INVALIDARG;
29881 
29882 if ((LONG)
29883  ulRecordNum >=
29884  m_rgErrors.
29885  GetCount ())
29886  return
29887  DB_E_BADRECORDNUM;
29888 
29889 
29890 CComPtr <
29891  IUnknown > spUnkCust;
29892 
29893 spUnkCust =
29894  m_rgErrors
29895  [ulRecordNum].
29896  spCustError;
29897 
29898 return spUnkCust->
29899  QueryInterface (riid,
29900  (void
29901  **)
29902  ppObject);
29903 
29904 
29905 }
29906 
29907 
29908 STDMETHOD
29909  (GetErrorInfo) (ULONG
29910  ulRecordNum,
29911  LCID,
29912  IErrorInfo
29913  **
29914  ppErrorInfo)
29915 
29916  {
29917 
29918 ATLTRACE
29919  (atlTraceDBProvider,
29920  2,
29921  _T
29922  ("IErrorRecordsImpl::GetErrorInfo\n"));
29923 
29924 
29925 if (ppErrorInfo ==
29926  NULL)
29927  return
29928  E_INVALIDARG;
29929 
29930 if ((LONG)
29931  ulRecordNum >=
29932  m_rgErrors.
29933  GetCount ())
29934  return
29935  DB_E_BADRECORDNUM;
29936 
29937 
29938 
29939 CComPtr <
29940  ICreateErrorInfo >
29941  spErrorInfo;
29942 
29943 
29944 if (FAILED
29945  (CreateErrorInfo
29946  (&spErrorInfo)))
29947 
29948  return
29949  E_OUTOFMEMORY;
29950 
29951 
29952 ERRORINFO & rInfo =
29953  *(m_rgErrors
29954  [ulRecordNum].
29955  pInfo);
29956 
29957 T * pT = (T *) this;
29958 
29959 spErrorInfo->
29960  SetDescription (pT->
29962  (rInfo));
29963 
29964 spErrorInfo->
29965  SetGUID (pT->
29966  GetErrorGUID
29967  (rInfo));
29968 
29969 spErrorInfo->
29970  SetHelpContext (pT->
29972  (rInfo));
29973 
29974 spErrorInfo->
29975  SetHelpFile (pT->
29977  (rInfo));
29978 
29979 spErrorInfo->
29980  SetSource (pT->
29982  (rInfo));
29983 
29984 return spErrorInfo->
29985  QueryInterface
29986  (__uuidof
29987  (IErrorInfo),
29988  (void **)
29989  ppErrorInfo);
29990 
29991 }
29992 
29993 
29994 STDMETHOD
29996  (ULONG ulRecordNum,
29997  DISPPARAMS *
29998  pdispparams)
29999  {
30000 
30001 ATLTRACE
30002  (atlTraceDBProvider,
30003  2,
30004  _T
30005  ("IErrorRecordsImpl::AddErrorRecord\n"));
30006 
30007 if (pdispparams ==
30008  NULL)
30009  return
30010  E_INVALIDARG;
30011 
30012 if ((LONG)
30013  ulRecordNum >=
30014  m_rgErrors.
30015  GetCount ())
30016  return
30017  DB_E_BADRECORDNUM;
30018 
30019 
30020 *pdispparams =
30021  m_rgErrors
30022  [ulRecordNum].
30023  dispparams;
30024 
30025 return S_OK;
30026 }
30027 
30028 
30029 STDMETHOD
30030  (GetRecordCount)
30031  (ULONG * pcRecords)
30032  {
30033 
30034 ATLTRACE
30035  (atlTraceDBProvider,
30036  2,
30037  _T
30038  ("IErrorRecordsImpl::GetErrorParameters\n"));
30039 
30040 if (pcRecords ==
30041  NULL)
30042  return
30043  E_INVALIDARG;
30044 
30045 *pcRecords =
30046  m_rgErrors.
30047  GetCount ();
30048 
30049 return S_OK;
30050 }
30051 
30052 
30053 LPOLESTR
30055  (ERRORINFO &)
30056  {
30057 
30058 return
30059  OLESTR
30060  ("The Error Description String");
30061 
30062 }
30063 
30064 
30065 REFGUID
30066  GetErrorGUID
30067  (ERRORINFO &)
30068  {
30069 
30070 return GUID_NULL;
30071 }
30072 
30073 
30074 DWORD
30076  (ERRORINFO &)
30077  {
30078 
30079 return 0;
30080 }
30081 
30082 
30083 LPOLESTR
30085  (ERRORINFO &)
30086  {
30087 
30088 return
30089  OLESTR
30090  ("The Error Help File");
30091 
30092 }
30093 
30094 
30095 LPOLESTR
30097  (ERRORINFO &)
30098  {
30099 
30100 return
30101  OLESTR
30102  ("The ErrorInfo");
30103 }
30104 
30105 
30106 CAtlArray <
30107  RecordClass >
30108  m_rgErrors;
30109 };
30110 
30111 
30112 
30113 
30114 class CTABLESRow
30115 
30116  {
30117 
30118 public:
30119 
30120 WCHAR
30121  m_szCatalog[129];
30122 
30123 WCHAR
30124  m_szSchema[129];
30125 
30126 WCHAR
30127  m_szTable[129];
30128 
30129 WCHAR m_szType[129];
30130 
30131 WCHAR m_szDesc[129];
30132 
30133 GUID m_guid;
30134 
30135 ULONG m_ulPropID;
30136 
30138 
30140 
30141 
30143  {
30144 
30145 wcscpy (&m_szCatalog
30146  [0], L"");
30147 
30148 wcscpy (&m_szSchema
30149  [0], L"");
30150 
30151 wcscpy (&m_szTable
30152  [0], L"");
30153 
30154 wcscpy (&m_szType
30155  [0], L"");
30156 
30157 wcscpy (&m_szDesc
30158  [0], L"");
30159 
30160 m_guid = GUID_NULL;
30161 
30162 m_ulPropID = 0;
30163 
30164 m_DateCreated = 0.0;
30165 
30167  0.0;
30168 }
30169 
30170 
30172  (CTABLESRow)
30174  ("TABLE_CATALOG", 1,
30175  m_szCatalog)
30177  ("TABLE_SCHEMA", 2,
30178  m_szSchema)
30180  ("TABLE_NAME", 3,
30181  m_szTable)
30183  ("TABLE_TYPE", 4,
30184  m_szType)
30186  ("TABLE_GUID", 5,
30187  0xFF, 0xFF,
30188  m_guid)
30190  ("DESCRIPTION", 6,
30191  m_szDesc)
30193  ("TABLE_PROPID", 7,
30194  10, 0xFF,
30195  m_ulPropID)
30197  ("DATE_CREATED", 8,
30198  DBTYPE_DATE, 0xFF,
30199  0xFF,
30200  m_DateCreated)
30202  ("DATE_MODIFIED", 9,
30203  DBTYPE_DATE, 0xFF,
30204  0xFF,
30205  m_DateModified)
30207  ()
30208 
30209 };
30210 
30211 
30212 
30213 class CCOLUMNSRow
30214 
30215  {
30216 
30217 public:
30218 
30219 WCHAR
30221  [129];
30222 
30223 WCHAR
30224  m_szTableSchema[129];
30225 
30226 WCHAR
30227  m_szTableName[129];
30228 
30229 WCHAR
30230  m_szColumnName[129];
30231 
30232 GUID m_guidColumn;
30233 
30234 ULONG
30236 
30237 ULONG
30239 
30240 VARIANT_BOOL
30242 
30243 WCHAR
30245  [129];
30246 
30247 ULONG
30249 
30250 VARIANT_BOOL
30251  m_bIsNullable;
30252 
30253 USHORT m_nDataType;
30254 
30255 GUID m_guidType;
30256 
30257 ULONG
30259 
30260 ULONG
30262 
30263 USHORT
30265 
30266 short
30268 
30269 ULONG
30271 
30272 WCHAR
30274  [129];
30275 
30276 WCHAR
30278  [129];
30279 
30280 WCHAR
30281  m_szCharSetName[129];
30282 
30283 WCHAR
30285  [129];
30286 
30287 WCHAR
30289  [129];
30290 
30291 WCHAR
30293  [129];
30294 
30295 WCHAR
30297  [129];
30298 
30299 WCHAR
30301  [129];
30302 
30303 WCHAR
30304  m_szDomainName[129];
30305 
30306 WCHAR
30307  m_szDescription[129];
30308 
30309 
30311  {
30312 
30313 ClearMembers ();
30314 
30315 }
30316 
30317 void
30319  {
30320 
30322  = NULL;
30323 
30324 m_szTableSchema[0] =
30325  NULL;
30326 
30327 m_szTableName[0] =
30328  NULL;
30329 
30330 m_szColumnName[0] =
30331  NULL;
30332 
30333 m_guidColumn =
30334  GUID_NULL;
30335 
30337  0;
30338 
30340  = 0;
30341 
30344 
30346  = NULL;
30347 
30348 m_ulColumnFlags = 0;
30349 
30350 m_bIsNullable =
30352 
30353 m_nDataType = 0;
30354 
30355 m_guidType =
30356  GUID_NULL;
30357 
30359  0;
30360 
30362  = 0;
30363 
30365  = 0;
30366 
30367 m_nNumericScale = 0;
30368 
30370  = 0;
30371 
30373  [0] = NULL;
30374 
30376  = NULL;
30377 
30378 m_szCharSetName[0] =
30379  NULL;
30380 
30382  [0] = NULL;
30383 
30385  [0] = NULL;
30386 
30388  = NULL;
30389 
30391  = NULL;
30392 
30394  = NULL;
30395 
30396 m_szDomainName[0] =
30397  NULL;
30398 
30399 m_szDescription[0] =
30400  NULL;
30401 }
30402 
30403 
30404 
30406  (CCOLUMNSRow)
30408  ("TABLE_CATALOG", 1,
30411  ("TABLE_SCHEMA", 2,
30412  m_szTableSchema)
30414  ("TABLE_NAME", 3,
30415  m_szTableName)
30417  ("COLUMN_NAME", 4,
30418  m_szColumnName)
30420  ("COLUMN_GUID", 5,
30421  0xFF, 0xFF,
30422  m_guidColumn)
30424  ("COLUMN_PROPID", 6,
30425  10, 0xFF,
30428  ("ORDINAL_POSITION",
30429  7, 10, 0xFF,
30431 
30433  ("COLUMN_HASDEFAULT",
30434  8, DBTYPE_BOOL,
30435  0xFF, 0xFF,
30437 
30439  ("COLUMN_DEFAULT", 9,
30440  0xFF, 0xFF,
30443  ("COLUMN_FLAGS", 10,
30444  10, 0xFF,
30445  m_ulColumnFlags)
30447  ("IS_NULLABLE", 11,
30448  DBTYPE_BOOL, 0xFF,
30449  0xFF,
30450  m_bIsNullable)
30452  ("DATA_TYPE", 12,
30453  DBTYPE_UI2, 5, 0xFF,
30454  m_nDataType)
30456  ("TYPE_GUID", 13,
30457  0xFF, 0xFF,
30458  m_guidType)
30460  ("CHARACTER_MAXIMUM_LENGTH",
30461  14, 10, 0xFF,
30464  ("CHARACTER_OCTET_LENGTH",
30465  15, 10, 0xFF,
30467 
30469  ("NUMERIC_PRECISION",
30470  16, 5, 0xFF,
30472 
30474  ("NUMERIC_SCALE", 17,
30475  5, 0xFF,
30476  m_nNumericScale)
30478  ("DATETIME_PRECISION",
30479  18, 10, 0xFF,
30481 
30483  ("CHARACTER_SET_CATALOG",
30484  19,
30486 
30488  ("CHARACTER_SET_SCHEMA",
30489  20,
30492  ("CHARACTER_SET_NAME",
30493  21,
30494  m_szCharSetName)
30496  ("COLLATION_CATALOG",
30497  22,
30499 
30501  ("COLLATION_SCHEMA",
30502  23,
30504 
30506  ("COLLATION_NAME",
30507  24,
30510  ("DOMAIN_CATALOG",
30511  25,
30514  ("DOMAIN_SCHEMA", 26,
30517  ("DOMAIN_NAME", 27,
30518  m_szDomainName)
30520  ("DESCRIPTION", 28,
30521  m_szDescription)
30523  ()
30524 };
30525 
30526 
30527 template <
30528  class ArrayClass >
30529 
30530 HRESULT
30532  (ArrayClass & rgData,
30533  DBID * pTableID,
30534  DBID * pIndexID,
30535  IUnknown * pSession,
30536  LONG *
30537  pcRowsAffected)
30538  {
30539 
30540 CComQIPtr <
30541  IOpenRowset >
30542  spOpenRowset =
30543  pSession;
30544 
30545 if (spOpenRowset ==
30546  NULL)
30547  return
30548  E_FAIL;
30549 
30550 CComPtr <
30551  IColumnsInfo >
30552  spColInfo;
30553 
30554 HRESULT hr =
30555  spOpenRowset->
30556  OpenRowset (NULL,
30557  pTableID,
30558  pIndexID,
30559  __uuidof
30560  (IColumnsInfo),
30561  0, NULL,
30562  (IUnknown
30563  **) &
30564  spColInfo);
30565 
30566 if (FAILED (hr))
30567  return hr;
30568 
30569 LPOLESTR szColumns =
30570  NULL;
30571 
30572 ULONG cColumns = 0;
30573 
30574 DBCOLUMNINFO *
30575  pColInfo = NULL;
30576 
30577 hr =
30578  spColInfo->
30579  GetColumnInfo
30580  (&cColumns,
30581  &pColInfo,
30582  &szColumns);
30583 
30584 if (FAILED (hr))
30585  return hr;
30586 
30587 *pcRowsAffected = 0;
30588 
30589 for (ULONG iCol = 0;
30590  iCol <
30591  cColumns;
30592  iCol++)
30593  {
30594 
30595 CCOLUMNSRow crData;
30596 
30597 DBCOLUMNINFO &
30598  rColCur =
30599  pColInfo[iCol];
30600 
30601 lstrcpynW (crData.
30602  m_szTableName,
30603  pTableID->
30604  uName.
30605  pwszName,
30607  (CCOLUMNSRow,
30608  m_szTableName));
30609 
30610 lstrcpynW (crData.
30611  m_szColumnName,
30612  rColCur.
30613  pwszName,
30615  (CCOLUMNSRow,
30616  m_szColumnName));
30617 
30618 lstrcpynW (crData.
30619  m_szDescription,
30620  rColCur.
30621  pwszName,
30623  (CCOLUMNSRow,
30624  m_szColumnName));
30625 
30626 GUID * pGuidCol =
30627  CDBIDOps::
30628  GetDBIDpGuid
30629  (rColCur.columnid);
30630 
30631 if (pGuidCol)
30632  crData.m_guidColumn =
30633  *pGuidCol;
30634  else
30635 
30636 crData.
30637  m_guidColumn =
30638  GUID_NULL;
30639 
30640 crData.
30641  m_ulColumnPropID =
30642  CDBIDOps::
30643  GetPropIDFromDBID
30644  (rColCur.columnid);
30645 
30646 crData.
30647  m_ulOrdinalPosition =
30648  rColCur.iOrdinal;
30649 
30650 crData.
30651  m_ulColumnFlags =
30652  rColCur.dwFlags;
30653 
30654 crData.
30655  m_bIsNullable =
30656  (rColCur.
30657  dwFlags &
30658  DBCOLUMNFLAGS_ISNULLABLE)
30659  ? ATL_VARIANT_TRUE :
30661 
30662 crData.m_nDataType =
30663  rColCur.wType;
30664 
30665 crData.
30666  m_ulCharMaxLength =
30667  rColCur.ulColumnSize;
30668 
30669 crData.
30670  m_nNumericPrecision =
30671  rColCur.bPrecision;
30672 
30673 crData.
30674  m_nNumericScale =
30675  rColCur.bScale;
30676  // if
30677  // (!rgData.Add(crData))
30678  // {
30679  // CoTaskMemFree(pColInfo);
30680  // CoTaskMemFree(szColumns);
30681  // return
30682  // E_OUTOFMEMORY;
30683  // }
30684  _ATLTRY
30685  {
30686 
30687 rgData.Add (crData);
30688 }
30689 
30690 _ATLCATCH (e)
30691  {
30692 
30693 _ATLDELETEEXCEPTION
30694  (e);
30695 
30696 CoTaskMemFree
30697  (pColInfo);
30698 
30699 CoTaskMemFree
30700  (szColumns);
30701 
30702 return
30703  E_OUTOFMEMORY;
30704 }
30705 
30706 
30707  (*pcRowsAffected)++;
30708 
30709 }
30710 
30711 
30712 CoTaskMemFree
30713  (pColInfo);
30714 
30715 CoTaskMemFree
30716  (szColumns);
30717 
30718 return S_OK;
30719 }
30720 
30721 
30722 class
30724  {
30725 
30726 public:
30727 // Attributes
30728  WCHAR m_szName[129];
30729 
30730 USHORT m_nType;
30731 
30732 ULONG m_ulSize;
30733 
30734 WCHAR
30735  m_szPrefix[129];
30736 
30737 WCHAR
30738  m_szSuffix[129];
30739 
30740 WCHAR
30741  m_szCreateParams
30742  [129];
30743 
30744 VARIANT_BOOL
30745  m_bIsNullable;
30746 
30747 VARIANT_BOOL
30748  m_bCaseSensitive;
30749 
30750 ULONG
30751  m_ulSearchable;
30752 
30753 VARIANT_BOOL
30754  m_bUnsignedAttribute;
30755 
30756 VARIANT_BOOL
30757  m_bFixedPrecScale;
30758 
30759 VARIANT_BOOL
30760  m_bAutoUniqueValue;
30761 
30762 WCHAR
30763  m_szLocalTypeName
30764  [129];
30765 
30766 short m_nMinScale;
30767 
30768 short m_nMaxScale;
30769 
30770 GUID m_guidType;
30771 
30772 WCHAR
30773  m_szTypeLib[129];
30774 
30775 WCHAR
30776  m_szVersion[129];
30777 
30778 VARIANT_BOOL
30779  m_bIsLong;
30780 
30781 VARIANT_BOOL
30782  m_bBestMatch;
30783 
30784 VARIANT_BOOL
30785  m_bIsFixedLength;
30786 
30787 
30788 
30790  ()
30791  {
30792 
30793 m_szName[0] = NULL;
30794 
30795 m_nType = 0;
30796 
30797 m_ulSize = 0;
30798 
30799 m_szPrefix[0] =
30800  NULL;
30801 
30802 m_szSuffix[0] =
30803  NULL;
30804 
30805 m_szCreateParams[0]
30806  = NULL;
30807 
30808 m_bIsNullable =
30810 
30811 m_bCaseSensitive =
30813 
30814 m_ulSearchable =
30815  DB_UNSEARCHABLE;
30816 
30817 m_bUnsignedAttribute
30819 
30820 m_bFixedPrecScale =
30822 
30823 m_bAutoUniqueValue =
30825 
30826 m_szLocalTypeName[0]
30827  = NULL;
30828 
30829 m_nMinScale = 0;
30830 
30831 m_nMaxScale = 0;
30832 
30833 m_guidType =
30834  GUID_NULL;
30835 
30836 m_szTypeLib[0] =
30837  NULL;
30838 
30839 m_szVersion[0] =
30840  NULL;
30841 
30842 m_bIsLong =
30844 
30845 m_bBestMatch =
30847 
30848 m_bIsFixedLength =
30850 
30851 }
30852 // Binding Maps
30856  ("TYPE_NAME", 1,
30857  m_szName)
30859  ("DATA_TYPE", 2,
30860  DBTYPE_UI2, 5, 0xFF,
30861  m_nType)
30863  ("COLUMN_SIZE", 3,
30864  10, 0xFF,
30865  m_ulSize)
30867  ("LITERAL_PREFIX", 4,
30868  m_szPrefix)
30870  ("LITERAL_SUFFIX", 5,
30871  m_szSuffix)
30873  ("CREATE_PARAMS", 6,
30874  m_szCreateParams)
30876  ("IS_NULLABLE", 7,
30877  DBTYPE_BOOL, 0xFF,
30878  0xFF,
30879  m_bIsNullable)
30881  ("CASE_SENSITIVE", 8,
30882  DBTYPE_BOOL, 0xFF,
30883  0xFF,
30884  m_bCaseSensitive)
30886  ("SEARCHABLE", 9, 10,
30887  0xFF,
30888  m_ulSearchable)
30890  ("UNSIGNED_ATTRIBUTE",
30891  10, DBTYPE_BOOL,
30892  0xFF, 0xFF,
30893  m_bUnsignedAttribute)
30894 
30896  ("FIXED_PREC_SCALE",
30897  11, DBTYPE_BOOL,
30898  0xFF, 0xFF,
30899  m_bFixedPrecScale)
30901  ("AUTO_UNIQUE_VALUE",
30902  12, DBTYPE_BOOL,
30903  0xFF, 0xFF,
30904  m_bAutoUniqueValue)
30905 
30907  ("LOCAL_TYPE_NAME",
30908  13,
30909  m_szLocalTypeName)
30911  ("MINIMUM_SCALE", 14,
30912  5, 0xFF,
30913  m_nMinScale)
30915  ("MAXIMUM_SCALE", 15,
30916  5, 0xFF,
30917  m_nMaxScale)
30919  ("GUID", 16, 0xFF,
30920  0xFF,
30921  m_guidType)
30923  ("TYPELIB", 17,
30924  m_szTypeLib)
30926  ("VERSION", 18,
30927  m_szVersion)
30929  ("IS_LONG", 19,
30930  DBTYPE_BOOL, 0xFF,
30931  0xFF,
30932  m_bIsLong)
30934  ("BEST_MATCH", 20,
30935  DBTYPE_BOOL, 0xFF,
30936  0xFF,
30937  m_bBestMatch)
30939  ("IS_FIXEDLENGTH",
30940  21, DBTYPE_BOOL,
30941  0xFF, 0xFF,
30942  m_bIsFixedLength)
30944  ()
30945 };
30946 
30947 
30948 
30949 class
30951  {
30952 
30953 public:
30954 
30955 WCHAR
30956  m_szSourcesName[256];
30957 
30958 WCHAR
30959  m_szSourcesParseName
30960  [256];
30961 
30962 WCHAR
30963  m_szSourcesDescription
30964  [256];
30965 
30966 unsigned short
30967  m_iType;
30968 
30969 VARIANT_BOOL
30970  m_bIsParent;
30971 
30972 
30974  (CEnumRowsetImpl)
30976  ("SOURCES_NAME", 1,
30977  m_szSourcesName)
30979  ("SOURCES_PARSENAME",
30980  2,
30981  m_szSourcesParseName)
30982 
30984  ("SOURCES_DESCRIPTION",
30985  3,
30986  m_szSourcesDescription)
30987 
30989  ("SOURCES_TYPE", 4,
30990  m_iType)
30992  ("SOURCES_ISPARENT",
30993  5,
30994  m_bIsParent)
30996  ()
30997 
30998 };
30999 
31000 
31002 // class IRowsetUpdateImpl
31003 
31004 template < class T, class Storage,
31005 class UpdateArray = CAtlArray < Storage >,
31006 class RowClass = CSimpleRow,
31007 class MapClass = CAtlMap < RowClass::KeyType, RowClass * >>
31008 class IRowsetUpdateImpl:public
31010  T, Storage,
31011  IRowsetUpdate,
31012  RowClass,
31013  MapClass >
31014  {
31015 
31016 public:
31017  // Destructor
31019 
31020  {
31021 
31023  RemoveAll ();
31024 }
31025 
31026  // IRowsetChange
31027  // Methods
31028  STDMETHOD (SetData)
31029  (HROW hRow,
31030  HACCESSOR hAccessor,
31031  void *pSrcData)
31032  {
31033 
31034 T * pT = (T *) this;
31035 
31036 
31038  Fire_OnFieldChange)
31039 
31040  {
31041 
31042  // Check to see if
31043  // someone is in an
31044  // event handler.
31045  // If we do, then
31046  // we should return
31047  // DB_E_NOTREENTRANT.
31048  if (!pT->
31049  IncrementMutex
31050  ())
31051  return
31052  DB_E_NOTREENTRANT;
31053  else
31054 
31055 pT->
31056  DecrementMutex ();
31057 }
31058 
31059 
31060  // We provide this
31061  // implementation
31062  // for use as it
31063  // adds more
31064  // complexity to the
31065  // SetData function
31066  // to handle both
31067  // immediate and
31068  // deferred
31069  // processing. It
31070  // also allows us to
31071  //
31072  // cache the
31073  // original data w/o
31074  // increasing the
31075  // size of
31076  // IRowsetChangeImpl
31077  RowClass * pRow;
31078 
31079 HRESULT hr;
31080 
31081  // Determine if we
31082  // are in immediate
31083  // or deferred mode,
31084  // if we are in
31085  // immediate mode
31086  // call FlushData.
31087  // Otherwise, add
31088  // the orginal data
31089  // to the cache
31090  CComVariant
31092 
31094 
31096  pT->
31097  GetPropValue
31098  (&DBPROPSET_ROWSET,
31099  DBPROP_IRowsetUpdate,
31100 
31101 &varDeferred);
31102 
31103 (FAILED (hr)
31104  || varDeferred.
31105  boolVal ==
31107  ? bDeferred =
31108  false : bDeferred =
31109  true;
31110 
31111 
31112 if (!pT->
31113  m_rgRowHandles.
31114  Lookup (hRow,
31115  pRow))
31116 
31117  return
31118  DB_E_BADROWHANDLE;
31119 
31120 
31121 if (hRow == NULL
31122  || pRow ==
31123  NULL)
31124  return
31125  DB_E_BADROWHANDLE;
31126 
31127  // If we've deleted
31128  // the row (or are
31129  // pending) then
31130  // SetData should
31131  // fail
31132  if (pRow->m_status ==
31133  DBPENDINGSTATUS_DELETED)
31134 
31135  return
31136  DB_E_DELETEDROW;
31137 
31138 
31140  {
31141 
31142 __if_exists (T::
31143  Fire_OnRowChange)
31144 
31145  {
31146 
31147 if (pRow->
31148  m_status !=
31149  DBPENDINGSTATUS_CHANGED
31150  &&
31151 pRow->
31152  m_status !=
31153  (DBPENDINGSTATUS_NEW
31154  |
31155  DBPENDINGSTATUS_UNCHANGED))
31156 
31157  {
31158 
31159 HRESULT hrNotify =
31160  pT->
31161  Fire_OnRowChange (pT,
31162  1,
31163  &hRow,
31164 
31165 DBREASON_ROW_FIRSTCHANGE,
31166  DBEVENTPHASE_OKTODO,
31167  FALSE);
31168 
31169 if ((hrNotify !=
31170  S_OK)
31171  && (hrNotify !=
31172  E_FAIL))
31173  return DB_E_CANCELED;
31174 
31175 
31176 hrNotify =
31177  pT->
31178  Fire_OnRowChange (pT,
31179  1,
31180  &hRow,
31181 
31182 DBREASON_ROW_FIRSTCHANGE,
31183  DBEVENTPHASE_ABOUTTODO,
31184  FALSE);
31185 
31186 if ((hrNotify !=
31187  S_OK)
31188  && (hrNotify !=
31189  E_FAIL))
31190  return DB_E_CANCELED;
31191 
31192 }
31193 
31194 }
31195 
31196 
31197  // If a row is soft
31198  // inserted (i.e.
31199  // haven't called
31200  // update yet)
31201  // then ignore this
31202  // section. An undo
31203  // will cause the
31204  // row to
31205  // delete.
31206  if (pRow->m_status !=
31207  DBPENDINGSTATUS_NEW)
31208 
31209  {
31210 
31211  // See if row is
31212  // already cached,
31213  // don't make any
31214  // changes
31215  // void* pData =
31216  // (void*)m_mapCachedData.Lookup(hRow,
31217  // pTemp);
31218  Storage * pData;
31219 
31220 if
31221  (!m_mapCachedData.
31222  Lookup (hRow,
31223  pData))
31224  {
31225 
31226 Storage * pam =
31227  NULL;
31228 
31229 ATLTRY (pam =
31230  new
31231  Storage);
31232 
31233 if (pam ==
31234  NULL)
31235  return
31236  E_OUTOFMEMORY;
31237 
31238 memcpy (pam,
31239  &pT->
31240  m_rgRowData
31241  [pRow->
31242  m_iRowset],
31243  sizeof
31244  (Storage));
31245 
31246 
31247 _ATLTRY
31248  {
31249 
31251  SetAt (hRow, pam);
31252 }
31253 
31254 _ATLCATCH (e)
31255  {
31256 
31257 _ATLDELETEEXCEPTION
31258  (e);
31259 return E_FAIL;
31260 
31261 }
31262 
31263 }
31264 
31265 }
31266 
31267 }
31268 
31269 
31270  // NOTE:
31271  // TransferData will
31272  // send the
31273  // SYNCHAFTER phase
31274  // of the
31275  // FIRSTCHANGE
31276  // notification
31277  // message. It will
31278  // handle a veto
31279  // internally.
31280  hr =
31281  TransferData < T,
31282  RowClass,
31283  MapClass >
31284 (pT,
31285  false,
31286  pSrcData,
31287  pRow,
31288  &(pT->
31289  m_rgRowHandles),
31290  hAccessor);
31291 
31292 if (FAILED (hr))
31293  return hr;
31294 
31295  // Flush Users Data,
31296  // if in immediate
31297  // mode
31298  if (!bDeferred)
31299  {
31300 
31301 HRESULT hrFlush = pT->FlushData (hRow, hAccessor);
31302 if (hrFlush == S_OK)
31303  return hr; // TransferData
31304  // may
31305  // have
31306  // returned
31307  // DB_S_ERRORSOCCURRED
31308  else
31309 
31310 return hrFlush;
31311 }
31312 
31313  else
31314 
31315  {
31316 
31317 __if_exists (T::
31318  Fire_OnRowChange)
31319 
31320  {
31321 
31322 if (pRow->
31323  m_status !=
31324  DBPENDINGSTATUS_CHANGED
31325  &&
31326 pRow->
31327  m_status !=
31328  (DBPENDINGSTATUS_NEW
31329  |
31330  DBPENDINGSTATUS_UNCHANGED))
31331 
31332  {
31333 
31334 pT->
31335  Fire_OnRowChange (pT,
31336  1,
31337  &hRow,
31338 
31339 DBREASON_ROW_FIRSTCHANGE,
31340  DBEVENTPHASE_DIDEVENT,
31341  TRUE);
31342 
31343 }
31344 
31345 }
31346 
31347 
31348 if (pRow->m_status != DBPENDINGSTATUS_NEW)
31349  pRow->m_status = DBPENDINGSTATUS_CHANGED;
31350 return hr; // TransferData
31351  // may
31352  // have
31353  // returned
31354  // DB_S_ERRORSOCCURRED
31355  }
31356 
31357 }
31358 
31359 
31360 
31361  // IRowsetUpdate
31362  // Methods
31363  STDMETHOD
31364  (GetOriginalData)
31365  (HROW hRow,
31366  HACCESSOR hAccessor,
31367  void *pData)
31368  {
31369 
31370 ATLTRACE
31371  (atlTraceDBProvider,
31372  2,
31373  _T
31374  ("IRowsetUpdateImpl::GetOriginalData\n"));
31375 
31376 
31377 T * pT =
31378  (T *) this;
31379 
31380 
31381 __if_exists (T::
31382  Fire_OnRowChange)
31383 
31384  {
31385 
31386  // Check to see if
31387  // someone is in an
31388  // event handler.
31389  // If we do, then
31390  // we should return
31391  // DB_E_NOTREENTRANT.
31392  if (!pT->
31393  IncrementMutex
31394  ())
31395  return
31396  DB_E_NOTREENTRANT;
31397  else
31398 
31399 pT->
31400  DecrementMutex ();
31401 }
31402 
31403 
31404  // Validate input
31405  // parameters
31406  T::_BindType *
31407  pBinding;
31408 
31409 bool bFound =
31410  pT->m_rgBindings.
31411  Lookup ((INT_PTR)
31412  hAccessor,
31413  pBinding);
31414 
31415 if (!bFound
31416  || pBinding ==
31417  NULL)
31418  return
31419  DB_E_BADACCESSORHANDLE;
31420 
31421 
31422 if (pData == NULL
31423  && pBinding->
31424  cBindings !=
31425  0)
31426  return
31427  E_INVALIDARG;
31428 
31429 
31430 RowClass * pRow;
31431 
31432 if (!pT->
31433  m_rgRowHandles.
31434  Lookup (hRow,
31435  pRow))
31436  return
31437  DB_E_BADROWHANDLE;
31438 
31439 if (hRow == NULL
31440  || pRow ==
31441  NULL)
31442  return
31443  DB_E_BADROWHANDLE;
31444 
31445  // If the status is
31446  // DBPENDINGSTATUS_INVALIDROW,
31447  // the row has been
31448  // deleted and the
31449  // change
31450  // transmitted to
31451  // the data source.
31452  // In
31453  // this case, we
31454  // can't get the
31455  // original data so
31456  // return
31457  // DB_E_DELETEDROW.
31458  if (pRow->m_status ==
31459  DBPENDINGSTATUS_INVALIDROW)
31460 
31461  return
31462  DB_E_DELETEDROW;
31463 
31464  // Note, need to
31465  // determine if
31466  // accessor is not a
31467  // row accessor
31468 
31469 
31470  // Determine if we
31471  // have a pending
31472  // insert. In this
31473  // case, the
31474  // spec says revert
31475  // to default
31476  // values, and if
31477  // defaults,
31478  // are not
31479  // available, then
31480  // NULLs.
31481 
31482 if (pRow->
31483  m_status ==
31484  DBPENDINGSTATUS_NEW)
31485 
31486  {
31487 
31488 ATLCOLUMNINFO *
31489  pInfo;
31490 
31491 bool bSucceeded =
31492  true;
31493 
31494 bool bFailed =
31495  false;
31496 
31497 DBORDINAL ulColumns;
31498 
31499 Storage temp;
31500 
31501 memcpy (&temp,
31502  &pT->
31503  m_rgRowData
31504  [pRow->
31505  m_iRowset],
31506  sizeof
31507  (Storage));
31508 
31509 
31510 pInfo =
31511  T::GetColumnInfo (pT,
31512  &ulColumns);
31513 
31514 
31515 for (ULONG lBind =
31516  0;
31517  lBind <
31518  pBinding->
31519  cBindings;
31520  lBind++)
31521  {
31522 
31523 DBBINDING *
31524  pBindCur =
31525  &(pBinding->
31526  pBindings[lBind]);
31527 
31528 ULONG lColInfo;
31529 
31530 for (lColInfo = 0;
31531  lColInfo <
31532  ulColumns
31533  &&
31534 pBindCur->
31535  iOrdinal !=
31536  pInfo
31537  [lColInfo].
31538  iOrdinal;
31539  lColInfo++);
31540 
31541 if (lColInfo ==
31542  ulColumns)
31543  return
31544  DB_E_BADORDINAL;
31545 
31546 
31547 ATLCOLUMNINFO *
31548  pColCur =
31549  &(pInfo[lColInfo]);
31550 
31551 DBSTATUS dbStat =
31552  DBSTATUS_S_DEFAULT;
31553 
31554 
31555  // Try to get the
31556  // default value.
31557  // if that doesn't
31558  // work, then
31559  // attempt to do a
31560  // NULL value
31561  if (FAILED
31562  (pT->
31563  SetDBStatus
31564  (&dbStat, pRow,
31565  pColCur)))
31566  {
31567 
31568 if ((pColCur->
31569  dwFlags &
31570  DBCOLUMNFLAGS_ISNULLABLE)
31571  ||
31572 (pColCur->
31573  dwFlags &
31575 
31576  {
31577 
31578 BYTE * pDstTemp =
31579  (BYTE
31580  *) (&(pT->
31581  m_rgRowData
31582  [pRow->
31583  m_iRowset]) +
31584  pColCur->
31585  cbOffset);
31586 
31587 *pDstTemp = NULL;
31588 
31589 if (pBindCur->
31590  dwPart &
31591  DBPART_STATUS)
31592  *((DBSTATUS
31593  *) ((BYTE
31594  *) (pData) +
31595  pBindCur->
31596  obStatus)) =
31597  DBSTATUS_S_ISNULL;
31598 
31599 bSucceeded |= true;
31600 
31601 continue;
31602 }
31603 
31604  else
31605 
31606  {
31607 
31608 if (pBindCur->
31609  dwPart &
31610  DBPART_STATUS)
31611  *((DBSTATUS
31612  *) ((BYTE
31613  *) (pData) +
31614  pBindCur->
31615  obStatus)) =
31616  DBSTATUS_E_UNAVAILABLE;
31617 
31618 bFailed = true;
31619 
31620 continue;
31621 }
31622 
31623 }
31624 
31625  else
31626 
31627  {
31628 
31629 if (pBindCur->
31630  dwPart &
31631  DBPART_STATUS)
31632  *((DBSTATUS
31633  *) ((BYTE
31634  *) (pData) +
31635  pBindCur->
31636  obStatus)) =
31637  DBSTATUS_S_OK;
31638 
31639 bSucceeded |= true;
31640 
31641 continue;
31642 }
31643 
31644 }
31645 
31646 
31647 TransferData < T,
31648  RowClass,
31649  MapClass >
31650 (pT,
31651  true,
31652  pData,
31653  pRow,
31654  &(pT->
31655  m_rgRowHandles),
31656  hAccessor);
31657 
31658 
31659 memcpy (&pT->
31660  m_rgRowData
31661  [pRow->
31662  m_iRowset],
31663  &temp,
31664  sizeof
31665  (Storage));
31666 
31667 if (!bFailed)
31668  return S_OK;
31669  else
31670 
31671 return (bSucceeded ?
31672  DB_S_ERRORSOCCURRED
31673  :
31674  DB_E_ERRORSOCCURRED);
31675 
31676 }
31677 
31678 
31679  // Determine if the
31680  // row is cached, if
31681  // so, we'll
31682  // temporarily
31683  // replace
31684  // it in m_rgRowData
31685  // and call
31686  // TransferData to
31687  // handle the
31688  // accessor.
31689  // It is kind of
31690  // strange but it
31691  // saves us from
31692  // having to
31693  // reimplement
31694  // TransferData
31695 
31696 Storage * pam;
31697 
31698 bFound =
31700  Lookup (hRow, pam);
31701 
31702 Storage temp;
31703 
31704 
31705 if (bFound
31706  && pam !=
31707  NULL)
31708  {
31709 
31710 memcpy (&temp,
31711  &pT->
31712  m_rgRowData
31713  [pRow->
31714  m_iRowset],
31715  sizeof
31716  (Storage));
31717 
31718 memcpy (&pT->
31719  m_rgRowData
31720  [pRow->
31721  m_iRowset],
31722  pam,
31723  sizeof
31724  (Storage));
31725 
31726 }
31727 
31728 
31729  // We need to trick
31730  // TransferData to
31731  // thinking a
31732  // non-transmitted
31733  // deleted row is
31734  // still alive.
31735  // This will be its
31736  // final state
31737  // after
31738  // we return
31739  // anyway.
31740  if (pRow->m_status ==
31741  DBPENDINGSTATUS_DELETED)
31742 
31743  pRow->m_status =
31744  DBPENDINGSTATUS_UNCHANGED;
31745 
31746 
31747 HRESULT hr =
31748  TransferData < T,
31749  RowClass,
31750  MapClass >
31751 (pT,
31752  true,
31753  pData,
31754  pRow,
31755  &(pT->
31756  m_rgRowHandles),
31757  hAccessor);
31758 
31759 
31760 if (bFound
31761  && pam !=
31762  NULL)
31763  {
31764 
31765 memcpy (&pT->
31766  m_rgRowData
31767  [pRow->
31768  m_iRowset],
31769  &temp,
31770  sizeof
31771  (Storage));
31772 
31773 }
31774 
31775 
31776 pRow->m_status =
31777  DBPENDINGSTATUS_UNCHANGED;
31778 
31779 return hr;
31780 }
31781 
31782 
31783 STDMETHOD (GetPendingRows) (HCHAPTER /* hReserved
31784  */
31785  ,
31786  DBPENDINGSTATUS
31787  dwRowStatus,
31788 
31789 DBCOUNTITEM
31790  *
31791  pcPendingRows,
31792  HROW
31793  **
31794  prgPendingRows,
31795 
31796 DBPENDINGSTATUS
31797  **
31798  prgPendingStatus)
31799 
31800  {
31801 
31802 ATLTRACE
31803  (atlTraceDBProvider,
31804  2,
31805  _T
31806  ("IRowsetUpdateImpl::GetPendingRows\n"));
31807 
31808 T * pT = (T *) this;
31809 
31810 bool bPending =
31811  false;
31812 
31813 RowClass * pRow =
31814  NULL;
31815  // DBROWCOUNT
31816  // ulRowHandles =
31817  // (DBROWCOUNT)pT->m_rgRowHandles.GetCount();
31818 
31819 if (pcPendingRows !=
31820  NULL)
31821  {
31822 
31823 *pcPendingRows = 0;
31824 
31825 
31826 if (prgPendingRows
31827  !=
31828  NULL)
31829  *prgPendingRows =
31830  NULL;
31831 
31832 
31833 if
31834  (prgPendingStatus !=
31835  NULL)
31836  *prgPendingStatus =
31837  NULL;
31838 }
31839 
31840 
31841  // Validate input
31842  // parameters
31843  if ((dwRowStatus &
31844 
31845 ~
31846  (DBPENDINGSTATUS_NEW
31847  |
31848  DBPENDINGSTATUS_CHANGED
31849  |
31850  DBPENDINGSTATUS_DELETED))
31851  !=
31852  0)
31853  return
31854  E_INVALIDARG;
31855 
31856  // Validate input
31857  // parameters
31858  if ((dwRowStatus &
31859 
31860 ~
31861  (DBPENDINGSTATUS_NEW
31862  |
31863  DBPENDINGSTATUS_CHANGED
31864  |
31865  DBPENDINGSTATUS_DELETED))
31866  !=
31867  0)
31868  return
31869  E_INVALIDARG;
31870 
31871  // Determine how
31872  // many rows we'll
31873  // need to return
31874 
31875 POSITION pos =
31876  pT->m_rgRowHandles.
31877  GetStartPosition ();
31878 
31879 while (pos !=
31880  NULL)
31881  {
31882 
31883 MapClass::CPair *
31884  pPair =
31885  pT->m_rgRowHandles.
31886  GetNext (pos);
31887 
31888 ATLASSERT (pPair !=
31889  NULL);
31890 
31891  // Check to see if a
31892  // row has a pending
31893  // status
31894  pRow =
31895  pPair->m_value;
31896 
31897 
31898 if (pRow->
31899  m_status &
31900  dwRowStatus)
31901  {
31902 
31903 if (pcPendingRows !=
31904  NULL)
31905  (*pcPendingRows)++;
31906 
31907 bPending = true;
31908 }
31909 
31910 }
31911 
31912  /*
31913  for (ULONG
31914  * iRowset = 0;
31915  * iRowset <
31916  * ulRowHandles;
31917  * iRowset++)
31918  {
31919  //
31920  * Check to see if a
31921  * row has a pending
31922  * status
31923  pRow =
31924  * pT->m_rgRowHandles.GetValueAt(iRowset);
31925  * if (pRow->m_status & dwRowStatus)
31926  {
31927  if
31928  * (pcPendingRows != NULL)
31929  * (*pcPendingRows)++;
31930  bPending = true;
31931  }
31932  * }
31933  */
31934 
31935  // In this case,
31936  // there are no
31937  // pending rows that
31938  // match, just exit
31939  // out
31940  if (!bPending)
31941  {
31942 
31943  // There are no
31944  // pending rows so
31945  // exit immediately
31946  return S_FALSE;
31947 }
31948 
31949  else
31950 
31951  {
31952 
31953  // Here' the
31954  // consumer just
31955  // wants to see if
31956  // there are pending
31957  // rows
31958  // we know that so
31959  // we can exit
31960  if (pcPendingRows ==
31961  NULL)
31962  return
31963  S_OK;
31964 }
31965 
31966 
31967  // Allocate arrays
31968  // for pending rows
31969  if (prgPendingRows !=
31970  NULL)
31971  {
31972 
31973 *prgPendingRows =
31974  (HROW *)
31975  CoTaskMemAlloc
31976  (*pcPendingRows *
31977  sizeof (HROW));
31978 
31979 if (*prgPendingRows
31980  == NULL)
31981  {
31982 
31983 *pcPendingRows = 0;
31984 
31985 return
31986  E_OUTOFMEMORY;
31987 }
31988 
31989 }
31990 
31991 
31992 if
31993  (prgPendingStatus !=
31994  NULL)
31995  {
31996 
31997 *prgPendingStatus =
31998  (DBPENDINGSTATUS *)
31999  CoTaskMemAlloc
32000  (*pcPendingRows *
32001  sizeof
32002  (DBPENDINGSTATUS));
32003 
32004 if
32005  (*prgPendingStatus ==
32006  NULL)
32007  {
32008 
32009 *pcPendingRows = 0;
32010 
32011 CoTaskMemFree
32012  (*prgPendingRows);
32013 
32014 *prgPendingRows =
32015  NULL;
32016 
32017 return
32018  E_OUTOFMEMORY;
32019 }
32020 
32021 memset
32022  (*prgPendingStatus,
32023  0,
32024  *pcPendingRows *
32025  sizeof
32026  (DBPENDINGSTATUS));
32027 
32028 }
32029 
32030 
32031 if (prgPendingRows
32032  ||
32033  prgPendingStatus)
32034 
32035  {
32036 
32037 ULONG ulRows = 0;
32038 
32039 pos =
32040  pT->m_rgRowHandles.
32041  GetStartPosition ();
32042 
32043 while (pos !=
32044  NULL)
32045  {
32046 
32047 MapClass::CPair *
32048  pPair =
32049  pT->m_rgRowHandles.
32050  GetNext (pos);
32051 
32052 ATLASSERT (pPair !=
32053  NULL);
32054 
32055 
32056 pRow =
32057  pPair->m_value;
32058 
32059 if (pRow->
32060  m_status &
32061  dwRowStatus)
32062  {
32063 
32064  // Add the output
32065  // row
32066  pRow->AddRefRow ();
32067 if (prgPendingRows)
32068  ((*prgPendingRows)[ulRows]) = /* (HROW)
32069  */ pPair->m_key;
32070  if (prgPendingStatus)
32071 
32072  ((*prgPendingStatus)
32073  [ulRows]) =
32074  (DBPENDINGSTATUS)
32075  pRow->m_status;
32076 
32077 ulRows++;
32078 }
32079 
32080 }
32081 
32082  /*
32083  for (iRowset =
32084  * 0; iRowset <
32085  * ulRowHandles;
32086  * iRowset++)
32087  {
32088  * pRow =
32089  * pT->m_rgRowHandles.GetValueAt(iRowset);
32090  * if (pRow->m_status & dwRowStatus)
32091  {
32092  //
32093  * Add the output row
32094  pRow->AddRefRow();
32095  * if (prgPendingRows)
32096  * ((*prgPendingRows)[ulRows]) =
32097  * (HROW)pT->m_rgRowHandles.GetKeyAt(iRowset);
32098  * if (prgPendingStatus)
32099  * ((*prgPendingStatus)[ulRows]) =
32100  * (DBPENDINGSTATUS)pRow->m_status;
32101  ulRows++;
32102  * }
32103  }
32104  */
32105  if (pcPendingRows !=
32106  NULL)
32107  *pcPendingRows =
32108  ulRows;
32109 }
32110 
32111 
32112  // Return code
32113  // depending on
32114  return S_OK;
32115 }
32116 
32117 
32118 STDMETHOD (GetRowStatus) (HCHAPTER /* hReserved
32119  */
32120  ,
32121  DBCOUNTITEM
32122  cRows,
32123 
32124 const
32125  HROW
32126  rghRows
32127  [],
32128  DBPENDINGSTATUS
32129  rgPendingStatus
32130  [])
32131 
32132  {
32133 
32134 ATLTRACE
32135  (atlTraceDBProvider,
32136  2,
32137  _T
32138  ("IRowsetUpdateImpl::GetRowStatus\n"));
32139 
32140 T * pT = (T *) this;
32141 
32142 
32143 bool bSucceeded =
32144  true;
32145 
32146 ULONG ulFetched = 0;
32147 
32148 
32149 if (cRows != 0)
32150  {
32151 
32152  // check for correct
32153  // pointers
32154  if (rghRows == NULL
32155  ||
32156  rgPendingStatus
32157  ==
32158  NULL)
32159  return
32160  E_INVALIDARG;
32161 
32162 
32163 for (ULONG ulRows =
32164  0;
32165  ulRows <
32166  cRows;
32167  ulRows++)
32168  {
32169 
32170 RowClass * pRow;
32171 
32172 bool bFound =
32173  pT->m_rgRowHandles.
32174  Lookup (rghRows
32175  [ulRows],
32176  pRow);
32177 
32178 if ((!bFound
32179  || pRow ==
32180  NULL)
32181  || (pRow->
32182  m_status ==
32183  DBPENDINGSTATUS_INVALIDROW))
32184 
32185  {
32186 
32187 rgPendingStatus
32188  [ulRows] =
32189  DBPENDINGSTATUS_INVALIDROW;
32190 
32191 bSucceeded = false;
32192 
32193 continue;
32194 }
32195 
32196 if (pRow->
32197  m_status !=
32198  0)
32199  rgPendingStatus
32200  [ulRows] =
32201  pRow->m_status;
32202  else
32203 
32204 rgPendingStatus
32205  [ulRows] =
32206  DBPENDINGSTATUS_UNCHANGED;
32207 
32208 
32209 ulFetched++;
32210 }
32211 
32212 }
32213 
32214 
32215 if (bSucceeded)
32216  {
32217 
32218 return S_OK;
32219 }
32220 
32221  else
32222 
32223  {
32224 
32225 if (ulFetched >
32226  0)
32227  return
32228  DB_S_ERRORSOCCURRED;
32229 
32230  else
32231 
32232 return
32233  DB_E_ERRORSOCCURRED;
32234 
32235 }
32236 
32237 }
32238 
32239 
32240 STDMETHOD (Undo) (HCHAPTER /* hReserved
32241  */
32242  ,
32243  DBCOUNTITEM
32244  cRows,
32245  const
32246  HROW
32247  rghRows
32248  [],
32249 
32250 DBCOUNTITEM
32251  *
32252  pcRowsUndone,
32253  HROW
32254  **
32255  prgRowsUndone,
32256 
32257 DBROWSTATUS
32258  **
32259  prgRowStatus)
32260 
32261  {
32262 
32263 ATLTRACE
32264  (atlTraceDBProvider,
32265  2,
32266  _T
32267  ("IRowsetUpdateImpl::Undo\n"));
32268 
32269 
32270 T * pT =
32271  (T *) this;
32272 
32273 T::
32274  ObjectLock lock (pT);
32275 
32276 
32277 __if_exists (T::
32278  Fire_OnRowChange)
32279 
32280  {
32281 
32282  // Check to see if
32283  // someone is in an
32284  // event handler.
32285  // If we do, then
32286  // we should return
32287  // DB_E_NOTREENTRANT.
32288  if (!pT->
32289  IncrementMutex
32290  ())
32291  {
32292 
32293  // Note, we can't
32294  // set this up above
32295  // as we may
32296  // inadvertantly
32297  // step on the
32298  // pcRowsUndone
32299  // variable.
32300  if (pcRowsUndone !=
32301  NULL)
32302  *pcRowsUndone = NULL;
32303 
32304 return
32305  DB_E_NOTREENTRANT;
32306 }
32307 
32308  else
32309 
32310 pT->
32311  DecrementMutex ();
32312 }
32313 
32314 
32315 DBCOUNTITEM ulRows
32316  = 0;
32317 
32318 bool bSucceeded =
32319  false;
32320 
32321 bool bFailed =
32322  false;
32323 
32324 bool bIgnore =
32325  false;
32326 
32327 ULONG ulUndone = 0;
32328 
32329 
32330  // the following
32331  // lines are used to
32332  // fix the two
32333  // _alloca calls
32334  // below. Those
32335  // calls are risky
32336  // because we may be
32337  // allocating huge
32338  // amounts of data.
32339  // So instead I'll
32340  // allocate that
32341  // data on heap.
32342  // But if you use
32343  // _alloca you don't
32344  // have to worry
32345  // about cleaning
32346  // this memory. So
32347  // we will use
32348  // these
32349  // temporary
32350  // variables to
32351  // allocate memory
32352  // on heap. As soon
32353  // as we exit the
32354  // function, the
32355  // memory will
32356  // be cleaned up,
32357  // just as if we
32358  // were using
32359  // alloca. So now,
32360  // instead of
32361  // calling alloca,
32362  // I'll alloc
32363  // memory on heap
32364  // using the two
32365  // smnart pointers
32366  // below, and then
32367  // assing it to the
32368  // actual pointers.
32369  CHeapPtr < HROW >
32370  spTempRowsUndone;
32371 
32372 CHeapPtr <
32373  DBROWSTATUS >
32374  spTempRowStatus;
32375 
32376 
32377 __if_exists (T::
32378  Fire_OnRowChange)
32379 
32380  {
32381 
32382 HRESULT hrNotify =
32383  S_OK;
32384 
32385 int nReason = 0;
32386 
32387 }
32388 
32389  // Ignore
32390  // prgRowsUndone/prgRowStatus
32391  // if pcRowsUndone
32392  // is NULL and
32393  // cRows == 0.
32394  if (pcRowsUndone !=
32395  NULL
32396  || cRows != 0)
32397  {
32398 
32399 if (prgRowsUndone !=
32400  NULL)
32401  *prgRowsUndone =
32402  NULL;
32403 
32404 
32405 if (prgRowStatus !=
32406  NULL)
32407  *prgRowStatus = NULL;
32408 
32409 }
32410 
32411  else
32412 
32413  {
32414 
32415 bIgnore = true; // Don't
32416  // do
32417  // status
32418  // or
32419  // row
32420  // arrays
32421  }
32422 
32423 
32424  // Check to see how
32425  // many changes
32426  // we'll undo
32427  if (pcRowsUndone !=
32428  NULL)
32429  {
32430 
32431 *pcRowsUndone =
32432  NULL;
32433 
32434 if (prgRowsUndone ==
32435  NULL)
32436  return
32437  E_INVALIDARG;
32438 }
32439 
32440 
32441 
32442 if (cRows != 0)
32443  {
32444 
32445 if (rghRows ==
32446  NULL)
32447  return
32448  E_INVALIDARG;
32449 
32450 
32451 ulRows = cRows;
32452 }
32453 
32454  else
32455 
32456 ulRows =
32457  (DBCOUNTITEM) pT->
32458  m_rgRowHandles.
32459  GetCount ();
32460 
32461  // NULL out
32462  // pointers
32463  if (prgRowsUndone !=
32464  NULL
32465  && ulRows != 0
32466  && bIgnore ==
32467  false)
32468  {
32469 
32470  // Make a temporary
32471  // buffer as we may
32472  // not fill up
32473  // everything
32474  // in the case where
32475  // cRows == 0
32476  if (cRows !=
32477  0)
32478  *prgRowsUndone =
32479  (HROW *)
32480  CoTaskMemAlloc
32481  (ulRows *
32482  sizeof (HROW));
32483  else
32484 
32485  {
32486 
32487  // *prgRowsUndone =
32488  // (HROW*)_alloca(ulRows
32489  // * sizeof(HROW));
32490  spTempRowsUndone.
32491  Allocate (ulRows);
32492 
32493 *prgRowsUndone =
32494  spTempRowsUndone;
32495 }
32496 
32497 
32498 if (*prgRowsUndone
32499  ==
32500  NULL)
32501  return
32502  E_OUTOFMEMORY;
32503 }
32504 
32505  else
32506 
32507  {
32508 
32509 if (prgRowsUndone !=
32510  NULL
32511  && bIgnore ==
32512  false)
32513  *prgRowsUndone =
32514  NULL;
32515 }
32516 
32517 
32518 if (prgRowStatus !=
32519  NULL
32520  && ulRows != 0
32521  && bIgnore ==
32522  false)
32523  {
32524 
32525 if (cRows !=
32526  0)
32527  *prgRowStatus =
32528  (DBROWSTATUS *)
32529  CoTaskMemAlloc
32530  (ulRows *
32531  sizeof
32532  (DBROWSTATUS));
32533  else
32534 
32535  {
32536 
32537  // *prgRowStatus =
32538  // (DBROWSTATUS*)_alloca(ulRows
32539  // *
32540  // sizeof(DBROWSTATUS));
32541  spTempRowStatus.
32542  Allocate (ulRows);
32543 
32544 *prgRowStatus =
32545  spTempRowStatus;
32546 }
32547 
32548 
32549 if (*prgRowStatus
32550  == NULL)
32551  {
32552 
32553 if (cRows !=
32554  0)
32555  CoTaskMemFree
32556  (*prgRowsUndone);
32557 
32558 *prgRowsUndone =
32559  NULL;
32560 
32561 return
32562  E_OUTOFMEMORY;
32563 }
32564 
32565 }
32566 
32567  else
32568 
32569  {
32570 
32571 if (prgRowStatus !=
32572  NULL
32573  && bIgnore ==
32574  false)
32575  *prgRowStatus = NULL;
32576 
32577 }
32578 
32579 
32580 POSITION pos =
32581  pT->m_rgRowHandles.
32582  GetStartPosition ();
32583 
32584 RowClass * pRow =
32585  NULL;
32586 
32587 for (ULONG ulUndoRow
32588  = 0;
32589  ulUndoRow <
32590  ulRows;
32591  ulUndoRow++)
32592  {
32593 
32594 HROW hRowUndo =
32595  NULL;
32596 
32597 ULONG ulCurrentRow =
32598  ulUndone;
32599 
32600 
32601 if (rghRows != NULL
32602  && cRows !=
32603  0)
32604  {
32605 
32606 hRowUndo =
32607  rghRows[ulUndoRow];
32608 
32609 }
32610 
32611  else
32612 
32613  {
32614 
32615 ATLASSERT (ulUndoRow
32616  <
32617  (ULONG)
32618  pT->
32619  m_rgRowHandles.
32620  GetCount
32621  ());
32622 
32623 ATLASSERT (pos !=
32624  NULL);
32625 
32626 MapClass::CPair *
32627  pPair =
32628  pT->m_rgRowHandles.
32629  GetNext (pos);
32630 
32631 ATLASSERT (pPair !=
32632  NULL);
32633 
32634 hRowUndo =
32635  pPair->m_key;
32636 }
32637 
32638 
32639 if (prgRowsUndone
32640  != NULL
32641  && bIgnore ==
32642  false)
32643  (*prgRowsUndone)
32644  [ulCurrentRow] =
32645  hRowUndo;
32646 
32647  // Fetch the
32648  // RowClass and
32649  // determine if it
32650  // is valid
32651  bool bFound =
32652  pT->m_rgRowHandles.
32653  Lookup (hRowUndo,
32654  pRow);
32655 
32656 if (!bFound
32657  || pRow ==
32658  NULL)
32659  {
32660 
32661 if (prgRowStatus !=
32662  NULL
32663  && bIgnore ==
32664  false)
32665  (*prgRowStatus)
32666  [ulCurrentRow] =
32667  DBROWSTATUS_E_INVALID;
32668 
32669 bFailed = true;
32670 
32671 ulUndone++;
32672 
32673 continue;
32674 }
32675 
32676 
32677  // If cRows is zero
32678  // we'll go through
32679  // all rows fetched.
32680  // We shouldn't
32681  // increment the
32682  // count for rows
32683  // that haven't been
32684  // modified.
32685 
32686 if (cRows != 0
32687  || (pRow != NULL
32688  &&
32689 pRow->
32690  m_status !=
32691  0
32692  && pRow->
32693  m_status !=
32694  DBPENDINGSTATUS_UNCHANGED
32695 
32696  &&pRow->
32697  m_status !=
32698  DBPENDINGSTATUS_INVALIDROW))
32699 
32700  ulUndone++;
32701  else
32702 
32703 continue;
32704 
32705 
32706  // AddRef the row if
32707  // cRows is zero (we
32708  // will be returning
32709  // it to the
32710  // consumer)
32711  if (cRows ==
32712  0)
32713  pRow->
32714  AddRefRow ();
32715 
32716  // Fetch the data,
32717  // note, this may be
32718  // NULL in several
32719  // cases
32720  Storage * pData;
32721 
32722 if
32723  (!m_mapCachedData.
32724  Lookup (hRowUndo,
32725  pData))
32726  pData = NULL;
32727 
32728 // long l = 0;
32729 
32730 switch (pRow->
32731  m_status)
32732  {
32733 
32734 case DBPENDINGSTATUS_INVALIDROW: // Row has already been hard deleted
32735 if (prgRowStatus != NULL && bIgnore == false)
32736  (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED;
32737 bFailed = true;
32738 continue;
32739 break;
32740 
32741 case DBPENDINGSTATUS_NEW: // Row
32742  // has
32743  // been
32744  // soft
32745  // inserted
32746  // If the row is
32747  // newly inserted,
32748  // go ahead and mark
32749  // its
32750  // row as INVALID
32751  // (according to the
32752  // specification).
32753 
32754 __if_exists (T::
32755  Fire_OnRowChange)
32756 
32757  {
32758 
32759 hrNotify =
32760  pT->
32761  Fire_OnRowChange (pT,
32762  1,
32763  &hRowUndo,
32764 
32765 DBREASON_ROW_UNDOINSERT,
32766  DBEVENTPHASE_OKTODO,
32767  FALSE);
32768 
32769 
32770 if ((hrNotify !=
32771  S_OK)
32772  && (hrNotify !=
32773  E_FAIL))
32774  {
32775 
32776 if (prgRowStatus !=
32777  NULL
32778  && bIgnore ==
32779  false)
32780  (*prgRowStatus)
32781  [ulCurrentRow] =
32782  DBROWSTATUS_E_CANCELED;
32783 
32784 bFailed = true;
32785 
32786 continue;
32787 }
32788 
32789 
32790 hrNotify =
32791  pT->
32792  Fire_OnRowChange (pT,
32793  1,
32794  &hRowUndo,
32795 
32796 DBREASON_ROW_UNDOINSERT,
32797  DBEVENTPHASE_ABOUTTODO,
32798  FALSE);
32799 
32800 
32801 if ((hrNotify !=
32802  S_OK)
32803  && (hrNotify !=
32804  E_FAIL))
32805  {
32806 
32807 if (prgRowStatus !=
32808  NULL
32809  && bIgnore ==
32810  false)
32811  (*prgRowStatus)
32812  [ulCurrentRow] =
32813  DBROWSTATUS_E_CANCELED;
32814 
32815 bFailed = true;
32816 
32817 continue;
32818 }
32819 
32820 
32821 hrNotify =
32822  pT->
32823  Fire_OnRowChange (pT,
32824  1,
32825  &hRowUndo,
32826 
32827 DBREASON_ROW_UNDOINSERT,
32828  DBEVENTPHASE_SYNCHAFTER,
32829  FALSE);
32830 
32831 
32832 if ((hrNotify !=
32833  S_OK)
32834  && (hrNotify !=
32835  E_FAIL))
32836  {
32837 
32838 if (prgRowStatus !=
32839  NULL
32840  && bIgnore ==
32841  false)
32842  (*prgRowStatus)
32843  [ulCurrentRow] =
32844  DBROWSTATUS_E_CANCELED;
32845 
32846 bFailed = true;
32847 
32848 continue;
32849 }
32850 
32851 }
32852 
32853 
32854 if (prgRowStatus !=
32855  NULL
32856  && bIgnore ==
32857  false)
32858  (*prgRowStatus)
32859  [ulCurrentRow] =
32860  DBROWSTATUS_S_OK;
32861 
32862 pT->m_rgRowData.
32863  RemoveAt (pRow->
32864  m_iRowset);
32865 
32866 
32867  // Move any other
32868  // subsequent rows
32869  // up in the chain
32870 // for (l=0; l<pT->m_rgRowHandles.GetCount(); l++)
32871 // {
32872  {
32873 
32874 POSITION pos =
32875  pT->m_rgRowHandles.
32876  GetStartPosition ();
32877 
32878 while (pos !=
32879  NULL)
32880  {
32881 
32882 MapClass::CPair *
32883  pPair =
32884  pT->m_rgRowHandles.
32885  GetNext (pos);
32886 
32887 ATLASSERT (pPair !=
32888  NULL);
32889 
32890 RowClass *
32891  pCheckRow =
32892  pPair->m_value;
32893 
32894 if (pCheckRow !=
32895  NULL
32896  &&
32897 pCheckRow->
32898  m_iRowset >
32899  pRow->
32900  m_iRowset)
32901  pCheckRow->
32902  m_iRowset--;
32903 }
32904 
32905 }
32906 
32907 
32908 pRow->m_status =
32909  DBPENDINGSTATUS_INVALIDROW;
32910 
32911 bSucceeded = true;
32912 
32913 
32914 __if_exists (T::
32915  Fire_OnRowChange)
32916 
32917  {
32918 
32919 pT->
32920  Fire_OnRowChange (pT,
32921  1,
32922  &hRowUndo,
32923  DBREASON_ROW_UNDOINSERT,
32924 
32925 DBEVENTPHASE_DIDEVENT,
32926  TRUE);
32927 
32928 }
32929 
32930 
32931 continue;
32932 break;
32933 
32934 case 0: // Row has just been fetched
32935 case DBPENDINGSTATUS_DELETED: // Row has been soft deleted
32936 case DBPENDINGSTATUS_UNCHANGED: // Row is not changed
32937  __if_exists (T::
32938  Fire_OnRowChange)
32939 
32940  {
32941 
32942 if (pRow->
32943  m_status ==
32944  DBPENDINGSTATUS_DELETED)
32945 
32946  {
32947 
32948 nReason = 1;
32949 
32950 hrNotify =
32951  pT->
32952  Fire_OnRowChange (pT,
32953  1,
32954  &hRowUndo,
32955 
32956 DBREASON_ROW_UNDODELETE,
32957  DBEVENTPHASE_OKTODO,
32958  FALSE);
32959 
32960 
32961 if ((hrNotify !=
32962  S_OK)
32963  && (hrNotify !=
32964  E_FAIL))
32965  {
32966 
32967 if (prgRowStatus !=
32968  NULL
32969  && bIgnore ==
32970  false)
32971  (*prgRowStatus)
32972  [ulCurrentRow] =
32973  DBROWSTATUS_E_CANCELED;
32974 
32975 bFailed = true;
32976 
32977 continue;
32978 }
32979 
32980 
32981 hrNotify =
32982  pT->
32983  Fire_OnRowChange (pT,
32984  1,
32985  &hRowUndo,
32986 
32987 DBREASON_ROW_UNDODELETE,
32988  DBEVENTPHASE_ABOUTTODO,
32989  FALSE);
32990 
32991 
32992 if ((hrNotify !=
32993  S_OK)
32994  && (hrNotify !=
32995  E_FAIL))
32996  {
32997 
32998 if (prgRowStatus !=
32999  NULL
33000  && bIgnore ==
33001  false)
33002  (*prgRowStatus)
33003  [ulCurrentRow] =
33004  DBROWSTATUS_E_CANCELED;
33005 
33006 bFailed = true;
33007 
33008 continue;
33009 }
33010 
33011 
33012 hrNotify =
33013  pT->
33014  Fire_OnRowChange (pT,
33015  1,
33016  &hRowUndo,
33017 
33018 DBREASON_ROW_UNDODELETE,
33019  DBEVENTPHASE_SYNCHAFTER,
33020  FALSE);
33021 
33022 
33023 if ((hrNotify !=
33024  S_OK)
33025  && (hrNotify !=
33026  E_FAIL))
33027  {
33028 
33029 if (prgRowStatus !=
33030  NULL
33031  && bIgnore ==
33032  false)
33033  (*prgRowStatus)
33034  [ulCurrentRow] =
33035  DBROWSTATUS_E_CANCELED;
33036 
33037 bFailed = true;
33038 
33039 continue;
33040 }
33041 
33042 }
33043 
33044 }
33045 
33046 
33047 pRow->m_status =
33048  DBPENDINGSTATUS_UNCHANGED;
33049 
33050 
33051 if (prgRowStatus !=
33052  NULL
33053  && bIgnore ==
33054  false)
33055  (*prgRowStatus)
33056  [ulCurrentRow] =
33057  DBROWSTATUS_S_OK;
33058 
33059 bSucceeded = true;
33060 
33061 
33062  // Somebody set,
33063  // then deleted a
33064  // row most likely
33065  if (pData !=
33066  NULL)
33067  memcpy (&pT->
33068  m_rgRowData
33069  [pRow->
33070  m_iRowset],
33071  pData,
33072  sizeof
33073  (Storage));
33074 
33075 
33076 __if_exists (T::
33077  Fire_OnRowChange)
33078 
33079  {
33080 
33081 if (nReason == 1)
33082  {
33083 
33084 pT->
33085  Fire_OnRowChange (pT,
33086  1,
33087  &hRowUndo,
33088  DBREASON_ROW_UNDODELETE,
33089 
33090 DBEVENTPHASE_DIDEVENT,
33091  TRUE);
33092 
33093 nReason = 0;
33094 }
33095 
33096 }
33097 
33098 continue;
33099 break;
33100 
33101 default: // Row has been changed
33102  __if_exists (T::
33103  Fire_OnRowChange)
33104 
33105  {
33106 
33107 hrNotify =
33108  pT->
33109  Fire_OnRowChange (pT,
33110  1,
33111  &hRowUndo,
33112 
33113 DBREASON_ROW_UNDOCHANGE,
33114  DBEVENTPHASE_OKTODO,
33115  FALSE);
33116 
33117 
33118 if ((hrNotify !=
33119  S_OK)
33120  && (hrNotify !=
33121  E_FAIL))
33122  {
33123 
33124 if (prgRowStatus !=
33125  NULL
33126  && bIgnore ==
33127  false)
33128  (*prgRowStatus)
33129  [ulCurrentRow] =
33130  DBROWSTATUS_E_CANCELED;
33131 
33132 bFailed = true;
33133 
33134 continue;
33135 }
33136 
33137 
33138 hrNotify =
33139  pT->
33140  Fire_OnRowChange (pT,
33141  1,
33142  &hRowUndo,
33143 
33144 DBREASON_ROW_UNDOCHANGE,
33145  DBEVENTPHASE_ABOUTTODO,
33146  FALSE);
33147 
33148 
33149 if ((hrNotify !=
33150  S_OK)
33151  && (hrNotify !=
33152  E_FAIL))
33153  {
33154 
33155 if (prgRowStatus !=
33156  NULL
33157  && bIgnore ==
33158  false)
33159  (*prgRowStatus)
33160  [ulCurrentRow] =
33161  DBROWSTATUS_E_CANCELED;
33162 
33163 bFailed = true;
33164 
33165 continue;
33166 }
33167 
33168 
33169 hrNotify =
33170  pT->
33171  Fire_OnRowChange (pT,
33172  1,
33173  &hRowUndo,
33174 
33175 DBREASON_ROW_UNDOCHANGE,
33176  DBEVENTPHASE_SYNCHAFTER,
33177  FALSE);
33178 
33179 
33180 if ((hrNotify !=
33181  S_OK)
33182  && (hrNotify !=
33183  E_FAIL))
33184  {
33185 
33186 if (prgRowStatus !=
33187  NULL
33188  && bIgnore ==
33189  false)
33190  (*prgRowStatus)
33191  [ulCurrentRow] =
33192  DBROWSTATUS_E_CANCELED;
33193 
33194 bFailed = true;
33195 
33196 continue;
33197 }
33198 
33199 }
33200 
33201 
33202 if (pData ==
33203  NULL)
33204  {
33205 
33206 __if_exists (T::
33207  Fire_OnRowChange)
33208 
33209  {
33210 
33211 pT->
33212  Fire_OnRowChange (pT,
33213  1,
33214  &hRowUndo,
33215  DBREASON_ROW_UNDOCHANGE,
33216 
33217 DBEVENTPHASE_FAILEDTODO,
33218  FALSE);
33219 
33220 }
33221 
33222 
33223 if (prgRowStatus !=
33224  NULL
33225  && bIgnore ==
33226  false)
33227  (*prgRowStatus)
33228  [ulCurrentRow] =
33229  DBROWSTATUS_E_INVALID;
33230 
33231 bFailed = true;
33232 
33233 continue;
33234 }
33235 
33236 
33237  // Copy data back
33238  memcpy (&pT->
33239  m_rgRowData
33240  [pRow->
33241  m_iRowset],
33242  pData,
33243  sizeof
33244  (Storage));
33245 
33246 if (prgRowStatus !=
33247  NULL
33248  && bIgnore ==
33249  false)
33250  (*prgRowStatus)
33251  [ulCurrentRow] =
33252  DBROWSTATUS_S_OK;
33253 
33254 pRow->m_status =
33255  DBPENDINGSTATUS_UNCHANGED;
33256 
33257 bSucceeded = true;
33258 
33259 
33260  // Remove undo
33261  // buffer
33263  RemoveKey (hRowUndo);
33264 
33265 
33266  // Check if we need
33267  // to release the
33268  // row because it's
33269  // ref was 0
33270  // See the
33271  // IRowset::ReleaseRows
33272  // section in the
33273  // spec for more
33274  // information
33275  if (pRow->m_dwRef ==
33276  0)
33277  {
33278 
33279 pRow->AddRefRow (); // Artifically
33280  // bump
33281  // this
33282  // to
33283  // remove
33284  // it
33285  if (FAILED
33286  (pT->
33287  RefRows (1,
33288  &hRowUndo,
33289  NULL,
33290  NULL,
33291  false)))
33292 
33293  return E_FAIL;
33294 }
33295 
33296 
33297 __if_exists (T::
33298  Fire_OnRowChange)
33299 
33300  {
33301 
33302 pT->
33303  Fire_OnRowChange (pT,
33304  1,
33305  &hRowUndo,
33306  DBREASON_ROW_UNDOCHANGE,
33307 
33308 DBEVENTPHASE_DIDEVENT,
33309  TRUE);
33310 
33311 }
33312 
33313 
33314 break;
33315 }
33316 
33317 }
33318 
33319 
33320 
33321  // Set the output
33322  // for rows undone.
33323  if (pcRowsUndone)
33324  *pcRowsUndone =
33325  ulUndone;
33326 
33327  // In the case where
33328  // cRows == 0, we
33329  // need to allocate
33330  // the final
33331  // array of data.
33332  if (cRows == 0)
33333  {
33334 
33335 HROW * prowTemp =
33336  NULL;
33337 
33338 DBROWSTATUS *
33339  prowStatus = NULL;
33340 
33341 
33342 if (prgRowsUndone
33343  != NULL
33344  && ulUndone !=
33345  0
33346  && bIgnore ==
33347  false)
33348  {
33349 
33350 prowTemp =
33351  (HROW *)
33352  CoTaskMemAlloc
33353  (ulUndone *
33354  sizeof (HROW));
33355 
33356 if (prowTemp ==
33357  NULL)
33358  {
33359 
33360  // Free
33361  // prgRowsUndone
33362  if (cRows != 0
33363  && prgRowsUndone
33364  !=
33365  NULL)
33366  CoTaskMemFree
33367  (*prgRowsUndone);
33368 
33369 
33370 if (cRows != 0
33371  && prgRowStatus
33372  !=
33373  NULL)
33374  CoTaskMemFree
33375  (*prgRowStatus);
33376 
33377 
33378 return
33379  E_OUTOFMEMORY;
33380 }
33381 
33382 
33383 memcpy (prowTemp, *prgRowsUndone, (sizeof (HROW) * ulUndone));
33384 if (cRows != 0)
33385  CoTaskMemFree (*prgRowsUndone); // we're
33386  // finished
33387  // w/
33388  // the
33389  // temp
33390  // array
33391  *prgRowsUndone =
33392  prowTemp;
33393 }
33394 
33395  else
33396 
33397  {
33398 
33399 if (prgRowsUndone !=
33400  NULL
33401  && bIgnore ==
33402  false)
33403  *prgRowsUndone =
33404  NULL;
33405 }
33406 
33407 
33408 if (prgRowStatus !=
33409  NULL
33410  && ulUndone !=
33411  0
33412  && bIgnore ==
33413  false)
33414  {
33415 
33416 prowStatus =
33417  (DBROWSTATUS *)
33418  CoTaskMemAlloc
33419  (ulUndone *
33420  sizeof
33421  (DBROWSTATUS));
33422 
33423 if (prowStatus ==
33424  NULL)
33425  {
33426 
33427 if (cRows != 0
33428  && prgRowsUndone
33429  !=
33430  NULL)
33431  CoTaskMemFree
33432  (*prgRowsUndone);
33433 
33434 
33435 if (prgRowStatus !=
33436  NULL
33437  && cRows !=
33438  0)
33439  CoTaskMemFree
33440  (*prgRowStatus);
33441 
33442 
33443 return
33444  E_OUTOFMEMORY;
33445 }
33446 
33447 
33448 memcpy (prowStatus,
33449  *prgRowStatus,
33450  (sizeof
33451  (DBROWSTATUS)
33452  *
33453  ulUndone));
33454 
33455 if (cRows !=
33456  0)
33457  CoTaskMemFree
33458  (*prgRowStatus);
33459 
33460 *prgRowStatus =
33461  prowStatus;
33462 }
33463 
33464  else
33465 
33466  {
33467 
33468 if (prgRowStatus !=
33469  NULL
33470  && bIgnore ==
33471  false)
33472  *prgRowStatus = NULL;
33473 
33474 }
33475 
33476 }
33477 
33478 
33479  // Send the return
33480  // value
33481  if (!bFailed)
33482  return S_OK;
33483  else
33484 
33485  {
33486 
33487 if (!bSucceeded)
33488  return
33489  DB_E_ERRORSOCCURRED;
33490 
33491  else
33492 
33493 return
33494  DB_S_ERRORSOCCURRED;
33495 
33496 }
33497 
33498 }
33499 
33500 
33501 STDMETHOD (Update) (HCHAPTER /* hReserved
33502  */
33503  ,
33504  DBCOUNTITEM
33505  cRows,
33506 
33507 const
33508  HROW
33509  rghRows
33510  [],
33511  DBCOUNTITEM
33512  *
33513  pcRows,
33514  HROW
33515  **
33516  prgRows,
33517 
33518 DBROWSTATUS
33519  **
33520  prgRowStatus)
33521 
33522  {
33523 
33524 ATLTRACE
33525  (atlTraceDBProvider,
33526  2,
33527  _T
33528  ("IRowsetUpdateImpl::Update\n"));
33529 
33530 
33531 T * pT =
33532  (T *) this;
33533 
33534 T::
33535  ObjectLock lock (pT);
33536 
33537 
33538 __if_exists (T::
33539  Fire_OnRowChange)
33540 
33541  {
33542 
33543  // Check to see if
33544  // someone is in an
33545  // event handler.
33546  // If we do, then
33547  // we should return
33548  // DB_E_NOTREENTRANT.
33549  if (!pT->
33550  IncrementMutex
33551  ())
33552  {
33553 
33554 if (pcRows !=
33555  NULL)
33556  *pcRows
33557  = NULL;
33558 
33559 return
33560  DB_E_NOTREENTRANT;
33561 }
33562 
33563  else
33564 
33565 pT->
33566  DecrementMutex ();
33567 }
33568 
33569 
33570 bool bSucceeded =
33571  false;
33572 
33573 bool bFailed =
33574  false;
33575 
33576 bool bIgnore =
33577  false;
33578 
33579 ULONG ulCount = 0;
33580 
33581 DBCOUNTITEM
33582  ulRowUpdate = 0;
33583 
33584  // the following
33585  // lines are used to
33586  // fix the two
33587  // _alloca calls
33588  // below. Those
33589  // calls are risky
33590  // because we may be
33591  // allocating huge
33592  // amounts of data.
33593  // So instead I'll
33594  // allocate that
33595  // data on heap.
33596  // But if you use
33597  // _alloca you don't
33598  // have to worry
33599  // about cleaning
33600  // this memory. So
33601  // we will use
33602  // these
33603  // temporary
33604  // variables to
33605  // allocate memory
33606  // on heap. As soon
33607  // as we exit the
33608  // function, the
33609  // memory will
33610  // be cleaned up,
33611  // just as if we
33612  // were using
33613  // alloca. So now,
33614  // instead of
33615  // calling alloca,
33616  // I'll alloc
33617  // memory on heap
33618  // using the two
33619  // smnart pointers
33620  // below, and then
33621  // assing it to the
33622  // actual pointers.
33623  CHeapPtr < HROW >
33624  spTempRows;
33625 
33626 CHeapPtr <
33627  DBROWSTATUS >
33628  spTempRowStatus;
33629 
33630 
33631 if (pcRows != NULL
33632  || cRows !=
33633  0)
33634  {
33635 
33636 if (prgRows !=
33637  NULL)
33638  *prgRows
33639  = NULL;
33640 
33641 
33642 if (prgRowStatus !=
33643  NULL)
33644  *prgRowStatus = NULL;
33645 
33646 }
33647 
33648  else
33649 
33650  {
33651 
33652 bIgnore = true;
33653 }
33654 
33655 
33656 if (pcRows !=
33657  NULL)
33658  {
33659 
33660 *pcRows = NULL;
33661 
33662 if (prgRows ==
33663  NULL)
33664  return
33665  E_INVALIDARG;
33666 }
33667 
33668 
33669 if (cRows != 0)
33670  {
33671 
33672 if (rghRows ==
33673  NULL)
33674  return
33675  E_INVALIDARG;
33676 
33677 
33678 ulRowUpdate =
33679  cRows;
33680 }
33681 
33682  else
33683 
33684 ulRowUpdate =
33685  (DBCOUNTITEM) pT->
33686  m_rgRowHandles.
33687  GetCount ();
33688 
33689  // NULL out
33690  // pointers
33691  if (prgRows != NULL
33692  && ulRowUpdate !=
33693  0
33694  && bIgnore ==
33695  false)
33696  {
33697 
33698 if (cRows !=
33699  0)
33700  *prgRows =
33701  (HROW *)
33702  CoTaskMemAlloc
33703  (ulRowUpdate *
33704  sizeof (HROW));
33705  else
33706 
33707  {
33708 
33709  // *prgRows =
33710  // (HROW*)_alloca(ulRowUpdate
33711  // * sizeof(HROW));
33712  spTempRows.
33713  Allocate
33714  (ulRowUpdate);
33715 
33716 *prgRows =
33717  spTempRows;
33718 }
33719 
33720 
33721 if (*prgRows ==
33722  NULL)
33723  return
33724  E_OUTOFMEMORY;
33725 }
33726 
33727  else
33728 
33729  {
33730 
33731 if (prgRows != NULL
33732  && bIgnore ==
33733  false)
33734  *prgRows = NULL;
33735 }
33736 
33737 
33738 if (prgRowStatus !=
33739  NULL
33740  && ulRowUpdate
33741  != 0
33742  && bIgnore ==
33743  false)
33744  {
33745 
33746 if (cRows !=
33747  0)
33748  *prgRowStatus =
33749  (DBROWSTATUS *)
33750  CoTaskMemAlloc
33751  (ulRowUpdate *
33752  sizeof
33753  (DBROWSTATUS));
33754  else
33755 
33756  {
33757 
33758  // *prgRowStatus =
33759  // (DBROWSTATUS*)_alloca(ulRowUpdate
33760  // *
33761  // sizeof(DBROWSTATUS));
33762  spTempRowStatus.
33763  Allocate
33764  (ulRowUpdate);
33765 
33766 *prgRowStatus =
33767  spTempRowStatus;
33768 }
33769 
33770 
33771 if (*prgRowStatus
33772  == NULL)
33773  {
33774 
33775 CoTaskMemFree
33776  (*prgRows);
33777 
33778 *prgRows = NULL;
33779 
33780 return
33781  E_OUTOFMEMORY;
33782 }
33783 
33784 }
33785 
33786  else
33787 
33788  {
33789 
33790 if (prgRowStatus !=
33791  NULL
33792  && bIgnore ==
33793  false)
33794  *prgRowStatus = NULL;
33795 
33796 }
33797 
33798 
33799  // NOTE: If cRows is
33800  // zero, then we
33801  // should ignore
33802  // rghRows and
33803  // update all of the
33804  // rows in the
33805  // cached map.
33806  RowClass * pRow =
33807  NULL;
33808 
33809 POSITION pos =
33810  pT->m_rgRowHandles.
33811  GetStartPosition ();
33812 
33813 for (ULONG ulRow =
33814  0;
33815  ulRow <
33816  ulRowUpdate;
33817  ulRow++)
33818  {
33819 
33820 void *pData = NULL;
33821 
33822 HROW hRowUpdate =
33823  NULL;
33824 
33825 ULONG
33826  ulAlreadyProcessed =
33827  0;
33828 
33829 bool bDupRow =
33830  false;
33831 
33832 LONG ulCurrentRow =
33833  ulCount;
33834 
33835  // Fetch the HROW,
33836  // RowClass, and
33837  // Data for the row.
33838  // Perform
33839  // Validation as
33840  // necessiary
33841  if (cRows != 0)
33842  {
33843 
33844 hRowUpdate =
33845  rghRows[ulRow];
33846 
33847 
33848 for (ULONG
33849  ulCheckDup =
33850  0;
33851  ulCheckDup <
33852  ulRow;
33853  ulCheckDup++)
33854 
33855  {
33856 
33857 if (pT->
33858  IsSameRow
33859  (hRowUpdate,
33860  rghRows
33861  [ulCheckDup])
33862  == S_OK)
33863  {
33864 
33865 ulAlreadyProcessed =
33866  ulCheckDup;
33867 
33868 bDupRow = true;
33869 
33870 break;
33871 }
33872 
33873 }
33874 
33875 }
33876 
33877  else
33878 
33879  {
33880 
33881 ATLASSERT (ulRow <
33882  (ULONG)
33883  pT->
33884  m_rgRowHandles.
33885  GetCount
33886  ());
33887 
33888 ATLASSERT (pos !=
33889  NULL);
33890 
33891 MapClass::CPair *
33892  pPair =
33893  pT->m_rgRowHandles.
33894  GetNext (pos);
33895 
33896 ATLASSERT (pPair !=
33897  NULL);
33898 
33899 hRowUpdate =
33900  pPair->m_key;
33901 }
33902 
33903 
33904 if (prgRows != NULL
33905  && bIgnore ==
33906  false)
33907  (*prgRows)
33908  [ulCurrentRow] =
33909  hRowUpdate;
33910 
33911 
33912 
33913 if (bDupRow !=
33914  false)
33915  {
33916 
33917  // We've already set
33918  // the row before,
33919  // just copy status
33920  // and
33921  // continue
33922  // processing
33923  // __if_exists(T::Fire_OnRowChange)
33924  // {
33925  // pT->Fire_OnRowChange(pT,
33926  // 1,
33927  // (HROW*)&hRowUpdate,
33928  // DBREASON_ROW_UPDATE,
33929  //
33930  // DBEVENTPHASE_DIDEVENT,
33931  // TRUE);
33932  // }
33933  if (prgRowStatus !=
33934  NULL
33935  && bIgnore ==
33936  false)
33937  (*prgRowStatus)
33938  [ulCurrentRow] =
33939  (*prgRowStatus)
33940  [ulAlreadyProcessed];
33941 
33942 
33943 ulCount++;
33944 
33945 continue;
33946 }
33947 
33948 
33949 bool bFound =
33950  pT->m_rgRowHandles.
33951  Lookup (hRowUpdate,
33952  pRow);
33953 
33954 if (!bFound
33955  || pRow ==
33956  NULL)
33957  {
33958 
33959 if (prgRowStatus !=
33960  NULL
33961  && bIgnore ==
33962  false)
33963  (*prgRowStatus)
33964  [ulCurrentRow] =
33965  DBROWSTATUS_E_INVALID;
33966 
33967 bFailed = true;
33968 
33969 ulCount++;
33970 
33971 continue;
33972 }
33973 
33974 
33975  // If the row is not
33976  // UNCHANGED, send
33977  // preliminary
33978  // notifications
33979  // before beginning
33980  // processing
33981  if (pRow->m_status !=
33982  0
33983  &&
33984 pRow->
33985  m_status !=
33986  DBPENDINGSTATUS_UNCHANGED)
33987 
33988  {
33989 
33990 __if_exists (T::
33991  Fire_OnRowChange)
33992 
33993  {
33994 
33995 
33996 HRESULT hrNotify =
33997  pT->
33998  Fire_OnRowChange (pT,
33999  1,
34000  &hRowUpdate,
34001  DBREASON_ROW_UPDATE,
34002 
34003 DBEVENTPHASE_OKTODO,
34004  FALSE);
34005 
34006 if ((hrNotify !=
34007  S_OK)
34008  && (hrNotify !=
34009  E_FAIL))
34010  {
34011 
34012 if (prgRowStatus !=
34013  NULL
34014  && bIgnore ==
34015  false)
34016  (*prgRowStatus)
34017  [ulCurrentRow] =
34018  DBROWSTATUS_E_CANCELED;
34019 
34020 bFailed = true;
34021 
34022 continue;
34023 }
34024 
34025 
34026 hrNotify =
34027  pT->
34028  Fire_OnRowChange (pT,
34029  1,
34030  &hRowUpdate,
34031  DBREASON_ROW_UPDATE,
34032 
34033 DBEVENTPHASE_ABOUTTODO,
34034  FALSE);
34035 
34036 if ((hrNotify !=
34037  S_OK)
34038  && (hrNotify !=
34039  E_FAIL))
34040  {
34041 
34042 if (prgRowStatus !=
34043  NULL
34044  && bIgnore ==
34045  false)
34046  (*prgRowStatus)
34047  [ulCurrentRow] =
34048  DBROWSTATUS_E_CANCELED;
34049 
34050 bFailed = true;
34051 
34052 continue;
34053 }
34054 
34055 
34056 hrNotify =
34057  pT->
34058  Fire_OnRowChange (pT,
34059  1,
34060  (HROW
34061  *)
34062  &
34063  hRowUpdate,
34064  DBREASON_ROW_UPDATE,
34065 
34066 DBEVENTPHASE_SYNCHAFTER,
34067  FALSE);
34068 
34069 
34070 if ((hrNotify !=
34071  S_OK)
34072  && (hrNotify !=
34073  E_FAIL))
34074  {
34075 
34076 if (prgRowStatus !=
34077  NULL
34078  && bIgnore ==
34079  false)
34080  (*prgRowStatus)
34081  [ulCurrentRow] =
34082  DBROWSTATUS_E_CANCELED;
34083 
34084 bFailed = true;
34085 
34086 continue;
34087 }
34088 
34089 }
34090 
34091 }
34092 
34093 
34094  // If cRows is zero
34095  // we'll go through
34096  // all rows fetched.
34097  // We
34098  // shouldn't
34099  // increment the
34100  // attempted count
34101  // for rows that
34102  // are
34103  // not changed
34104  if (cRows != 0
34105  || (pRow != NULL
34106  &&
34107 pRow->
34108  m_status != 0
34109  && pRow->
34110  m_status !=
34111  DBPENDINGSTATUS_UNCHANGED
34112 
34113  &&pRow->
34114  m_status !=
34115  DBPENDINGSTATUS_INVALIDROW))
34116 
34117  ulCount++;
34118  else
34119 
34120 continue;
34121 
34122 
34123 
34124 switch (pRow->
34125  m_status)
34126 
34127  {
34128 
34129 case DBPENDINGSTATUS_INVALIDROW: // Row is bad or deleted
34130  __if_exists (T::
34131  Fire_OnRowChange)
34132 
34133  {
34134 
34135 pT->
34136  Fire_OnRowChange (pT,
34137  1,
34138  (HROW
34139  *)
34140  &
34141  hRowUpdate,
34142  DBREASON_ROW_UPDATE,
34143 
34144 DBEVENTPHASE_FAILEDTODO,
34145  TRUE);
34146 
34147 }
34148 
34149 if (prgRowStatus != NULL && bIgnore == false)
34150  (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED;
34151 bFailed = true;
34152 continue;
34153 break;
34154 
34155 case DBPENDINGSTATUS_UNCHANGED:
34156 
34157 case 0:
34158 
34159  // If the row's
34160  // status is not
34161  // changed, then
34162  // just put S_OK
34163  // and continue.
34164  // The spec says we
34165  // should not
34166  // transmit the
34167  // request to the
34168  // data source (as
34169  // nothing would
34170  // change).
34171  // __if_exists(T::Fire_OnRowChange)
34172  // {
34173  // pT->Fire_OnRowChange(pT,
34174  // 1,
34175  // (HROW*)&hRowUpdate,
34176  // DBREASON_ROW_UPDATE,
34177  //
34178  // DBEVENTPHASE_DIDEVENT,
34179  // TRUE);
34180  // }
34181 if (prgRowStatus != NULL && bIgnore == false)
34182  (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK;
34183 bSucceeded = true;
34184 continue;
34185 break;
34186 
34187 default:
34188 
34189 pData =
34190  &pT->
34191  m_rgRowData[pRow->
34192  m_iRowset];
34193 
34194 
34195 if (pData ==
34196  NULL)
34197  {
34198 
34199 __if_exists (T::
34200  Fire_OnRowChange)
34201 
34202  {
34203 
34204 pT->
34205  Fire_OnRowChange (pT,
34206  1,
34207  (HROW
34208  *)
34209  &
34210  hRowUpdate,
34211  DBREASON_ROW_UPDATE,
34212 
34213 DBEVENTPHASE_FAILEDTODO,
34214  TRUE);
34215 
34216 }
34217 
34218 if (prgRowStatus !=
34219  NULL
34220  && bIgnore ==
34221  false)
34222  (*prgRowStatus)
34223  [ulCurrentRow] =
34224  DBROWSTATUS_E_INVALID;
34225 
34226 bFailed = true;
34227 
34228 continue;
34229 }
34230 
34231 
34232  // If the rghRows
34233  // variable is NULL,
34234  // we now add the
34235  // row to
34236  // prgRows. We do
34237  // this because we
34238  // have determined
34239  // that the
34240  // row has changed.
34241  // AddRef the row as
34242  // it may not be
34243  // held by
34244  // the consumer.
34245  if (cRows ==
34246  0)
34247  pRow->
34248  AddRefRow ();
34249 
34250  // Ask the provider
34251  // if it is OK to
34252  // change this row.
34253  DBROWSTATUS status =
34254  DBROWSTATUS_S_OK;
34255 
34256 if (FAILED
34258  (pRow->
34259  m_status,
34260  hRowUpdate,
34261  &status)))
34262  {
34263 
34264 __if_exists (T::
34265  Fire_OnRowChange)
34266 
34267  {
34268 
34269 pT->
34270  Fire_OnRowChange (pT,
34271  1,
34272  (HROW
34273  *)
34274  &
34275  hRowUpdate,
34276  DBREASON_ROW_UPDATE,
34277 
34278 DBEVENTPHASE_FAILEDTODO,
34279  TRUE);
34280 
34281 }
34282 
34283 if (prgRowStatus !=
34284  NULL
34285  && bIgnore ==
34286  false)
34287  (*prgRowStatus)
34288  [ulCurrentRow] =
34289  status;
34290 
34291 bFailed = true;
34292 
34293 continue;
34294 }
34295 
34296 
34297 if (pRow->
34298  m_status ==
34299  DBPENDINGSTATUS_DELETED)
34300 
34301  {
34302 
34303 pT->m_rgRowData.
34304  RemoveAt (pRow->
34305  m_iRowset);
34306 
34307  // Need to update
34308  // any outstanding
34309  // pRow->m_iRowset
34310  // variables
34311  POSITION pos =
34312  pT->m_rgRowHandles.
34313  GetStartPosition ();
34314 
34315 while (pos !=
34316  NULL)
34317  {
34318 
34319 MapClass::CPair *
34320  pPair =
34321  pT->m_rgRowHandles.
34322  GetNext (pos);
34323 
34324 ATLASSERT (pPair !=
34325  NULL);
34326 
34327 RowClass *
34328  pCheckRow =
34329  pPair->m_value;
34330 
34331 if (pCheckRow !=
34332  NULL
34333  &&
34334 pCheckRow->
34335  m_iRowset >
34336  pRow->
34337  m_iRowset)
34338  pCheckRow->
34339  m_iRowset--;
34340 }
34341 
34342 
34343  // Per the
34344  // specification,
34345  // deleted rows
34346  // transmitted
34347  // to the data
34348  // source are set to
34349  //
34350  // DBPENDINGSTATUS_INVALIDROW
34351  pRow->m_status =
34352  DBPENDINGSTATUS_INVALIDROW;
34353 
34354 }
34355 
34356 
34357  // Copy data back
34358  if (FAILED
34359  (pT->
34360  FlushData
34361  (hRowUpdate,
34362  NULL)))
34363  {
34364 
34365 if (prgRowStatus !=
34366  NULL
34367  && bIgnore ==
34368  false)
34369  (*prgRowStatus)
34370  [ulCurrentRow] =
34371  DBROWSTATUS_E_FAIL;
34372 
34373 __if_exists (T::
34374  Fire_OnRowChange)
34375 
34376  {
34377 
34378 pT->
34379  Fire_OnRowChange (pT,
34380  1,
34381  (HROW
34382  *)
34383  &
34384  hRowUpdate,
34385  DBREASON_ROW_UPDATE,
34386 
34387 DBEVENTPHASE_FAILEDTODO,
34388  TRUE);
34389 
34390 }
34391 
34392 bFailed = true;
34393 
34394 continue;
34395 }
34396 
34397 
34398 if (prgRowStatus !=
34399  NULL
34400  && bIgnore ==
34401  false)
34402  (*prgRowStatus)
34403  [ulCurrentRow] =
34404  DBROWSTATUS_S_OK;
34405 
34406 bSucceeded = true;
34407 
34408 
34409 if (pRow->
34410  m_status !=
34411  DBPENDINGSTATUS_DELETED)
34412 
34413  {
34414 
34415 if (pRow->
34416  m_status !=
34417  DBPENDINGSTATUS_INVALIDROW)
34418 
34419  pRow->m_status =
34420  DBPENDINGSTATUS_UNCHANGED;
34421 
34422 }
34423 
34424 
34425  // Remove undo
34426  // buffer.
34427  if (m_mapCachedData.
34428  Lookup
34429  (hRowUpdate) !=
34430  NULL)
34432  RemoveKey
34433  (hRowUpdate);
34434 
34435  // remove the ref
34436  // count if the
34437  // consumer didn't
34438  // have a handle.
34439 // if (rghRows == NULL)
34440 // pRow->ReleaseRow();
34441 
34442  // Check if we need
34443  // to release the
34444  // row because it's
34445  // ref was 0
34446  // See the
34447  // IRowset::ReleaseRows
34448  // section in the
34449  // spec for more
34450  // information
34451  if (pRow->m_dwRef ==
34452  0)
34453  {
34454 
34455 pRow->AddRefRow (); // Artifically
34456  // bump
34457  // this
34458  // to
34459  // remove
34460  // it
34461  if (FAILED
34462  (pT->
34463  RefRows (1,
34464  &hRowUpdate,
34465  NULL,
34466  NULL,
34467  false)))
34468 
34469  return E_FAIL;
34470 }
34471 
34472 
34473 __if_exists (T::
34474  Fire_OnRowChange)
34475 
34476  {
34477 
34478 pT->
34479  Fire_OnRowChange (pT,
34480  1,
34481  (HROW
34482  *)
34483  &
34484  hRowUpdate,
34485  DBREASON_ROW_UPDATE,
34486 
34487 DBEVENTPHASE_DIDEVENT,
34488  TRUE);
34489 
34490 }
34491 
34492 
34493 break;
34494 
34495 }
34496 
34497 }
34498 
34499 
34500  // Set the output
34501  // for rows undone.
34502  if (pcRows)
34503  {
34504 
34505 if (cRows ==
34506  0)
34507  *pcRows =
34508  ulCount;
34509  else
34510 
34511 *pcRows = cRows;
34512 }
34513 
34514 
34515  // In the case where
34516  // cRows == 0, we
34517  // need to allocate
34518  // the final
34519  // array of HROWs
34520  // and status
34521  // values.
34522  if (cRows == 0)
34523  {
34524 
34525 HROW * prowTemp;
34526 
34527 DBROWSTATUS *
34528  prowStatus;
34529 
34530 
34531 if (prgRows != NULL
34532  && ulCount != 0
34533  && bIgnore ==
34534  false)
34535  {
34536 
34537 prowTemp =
34538  (HROW *)
34539  CoTaskMemAlloc
34540  (ulCount *
34541  sizeof (HROW));
34542 
34543 if (prowTemp ==
34544  NULL)
34545  {
34546 
34547 if (cRows != 0
34548  && prgRows !=
34549  NULL)
34550  CoTaskMemFree
34551  (*prgRows);
34552 
34553 
34554 if (cRows != 0
34555  && prgRowStatus
34556  !=
34557  NULL)
34558  CoTaskMemFree
34559  (*prgRowStatus);
34560 
34561 
34562 return
34563  E_OUTOFMEMORY;
34564 }
34565 
34566 
34567 memcpy (prowTemp,
34568  *prgRows,
34569  sizeof
34570  (HROW) *
34571  ulCount);
34572 
34573 if (cRows !=
34574  0)
34575  CoTaskMemFree
34576  (*prgRows);
34577 
34578 *prgRows = prowTemp;
34579 
34580 }
34581 
34582  else
34583 
34584  {
34585 
34586 if (prgRows != NULL
34587  && bIgnore ==
34588  false)
34589  *prgRows = NULL;
34590 }
34591 
34592 
34593 if (prgRowStatus !=
34594  NULL
34595  && ulCount != 0
34596  && bIgnore ==
34597  false)
34598  {
34599 
34600 prowStatus =
34601  (DBROWSTATUS *)
34602  CoTaskMemAlloc
34603  (ulCount *
34604  sizeof
34605  (DBROWSTATUS));
34606 
34607 if (prowStatus ==
34608  NULL)
34609  {
34610 
34611 if (cRows != 0
34612  && prgRows !=
34613  NULL)
34614  CoTaskMemFree
34615  (*prgRows);
34616 
34617 
34618 if (cRows != 0
34619  && prgRowStatus
34620  !=
34621  NULL)
34622  CoTaskMemFree
34623  (*prgRowStatus);
34624 
34625 
34626 return
34627  E_OUTOFMEMORY;
34628 }
34629 
34630 
34631 memcpy (prowStatus,
34632  *prgRowStatus,
34633  (sizeof
34634  (DBROWSTATUS)
34635  *
34636  ulCount));
34637 
34638 if (cRows !=
34639  0)
34640  CoTaskMemFree
34641  (*prgRowStatus);
34642 
34643 *prgRowStatus =
34644  prowStatus;
34645 }
34646 
34647  else
34648 
34649  {
34650 
34651 if (prgRowStatus !=
34652  NULL
34653  && bIgnore ==
34654  false)
34655  *prgRowStatus = NULL;
34656 
34657 }
34658 
34659 }
34660 
34661 
34662  // Send the return
34663  // value
34664  if (!bFailed)
34665  return S_OK;
34666  else
34667 
34668  {
34669 
34670 if (!bSucceeded)
34671  return
34672  DB_E_ERRORSOCCURRED;
34673 
34674  else
34675 
34676 return
34677  DB_S_ERRORSOCCURRED;
34678 
34679 }
34680 
34681 }
34682 
34683 
34684 
34685  // Callback
34686  // functions
34687  HRESULT IsUpdateAllowed (DBPENDINGSTATUS /* [in]
34688  *//* status
34689  */
34690  ,
34691  /* [in]
34692  */ HROW
34693  /* hRowUpdate
34694  */
34695  ,
34696  /* [out]
34697  */
34698  DBROWSTATUS
34699  *
34700  /* pRowStatus
34701  */
34702  )
34703  {
34704 
34705  // If you need to
34706  // perform any
34707  // checks for
34708  // security,
34709  // integrity
34710  // violations, etc.
34711  // as a result of an
34712  // update, override
34713  // this
34714  // method.
34715 
34716  // Make sure you put
34717  // the appropriate
34718  // status in the
34719  // pRowStatus
34720  // as it will be
34721  // returned to the
34722  // user.
34723  return S_OK;
34724 }
34725 
34726 
34727  // Map containing
34728  // original data for
34729  // deferred
34730  // operation
34731  CAtlMap < HROW,
34732  Storage *
34733  >m_mapCachedData;
34734 };
34735 
34736 
34737 }; // namespace
34738 
34739  // ATL
34740 
34741 #pragma warning(pop)
34742 
34743 #endif // __ATLDB_H__
m_szCatalog PROVIDER_COLUMN_ENTRY_WSTR("TABLE_SCHEMA", 2, m_szSchema) PROVIDER_COLUMN_ENTRY_WSTR("TABLE_NAME"
HRESULT GetUPropInfoPtr(ULONG iPropSetDex, DBPROPID dwPropertyId, UPROPINFO **ppUPropInfo)
LPOLESTR GetErrorHelpFile(ERRORINFO &)
HRESULT InitFromRowset(ArrayClass &rgData, DBID *pTableID, DBID *pIndexID, IUnknown *pSession, LONG *pcRowsAffected)
Definition: atldb_orig.h:30532
theClass _Class
Definition: atldb_orig.h:18597
CAutoVectorPtr< DWORD > m_rgdwPropsInError
LPOLESTR DBORDINAL ordinal
Definition: atldb_orig.h:18671
WCHAR m_szType[129]
UPROPINFO * pUPropInfo
Definition: atldb_cubrid.h:451
ULONG iCurSet
Definition: Rowset.h:132
OUT_OF_LINE HRESULT FInit(CUtlPropsBase *pCopyMe=NULL)=0
type
Definition: atldb_orig.h:18759
HRESULT _SchemaSupport(GUID **ppGuid, IUnknown *pUnkOuter, REFIID rguidSchema, ULONG cRestrictions, const VARIANT rgRestrictions [], REFIID riid, ULONG cPropertySets, DBPROPSET rgPropertySets [], IUnknown **ppRowset) \
Definition: atldb_orig.h:13313
#define SIZEOF_MEMBER(memberOf, member)
WCHAR m_szDescription[129]
const GUID * pPropSet
Definition: atldb_cubrid.h:447
DBBINDING * pBindings
Definition: atldb_cubrid.h:463
BEGIN_COM_MAP(CRowsetImpl) COM_INTERFACE_ENTRY(IRowsetInfo) COM_INTERFACE_ENTRY(IAccessor) COM_INTERFACE_ENTRY(IObjectWithSite) COM_INTERFACE_ENTRY(IColumnsInfo) COM_INTERFACE_ENTRY(IConvertType) COM_INTERFACE_ENTRY(IRowsetIdentity) COM_INTERFACE_ENTRY(IRowset) HRESULT FinalConstruct()
#define PROVIDER_COLUMN_ENTRY(name, ordinal, member)
Definition: atldb_orig.h:18707
#define _ATLDUMPPROPSETIID(iid, dwStatus)
Definition: atldb_orig.h:326
ULONG m_ulColumnPropID
REFGUID GetErrorGUID(ERRORINFO &)
HRESULT ValidateBindings(DBCOUNTITEM cBindings, const DBBINDING rgBindings[], DBBINDSTATUS rgStatus[], bool bHasBookmarks, DBACCESSORFLAGS dwAccessorFlags, DBLENGTH cbRowSize)
DWORD ReleaseRow()
Definition: atldb_orig.h:19020
STDMETHOD() Undo(HCHAPTER, DBCOUNTITEM cRows, const HROW rghRows [], DBCOUNTITEM *pcRowsUndone, HROW **prgRowsUndone, DBROWSTATUS **prgRowStatus)
DBACCESSORFLAGS dwAccessorFlags
Definition: atldb_cubrid.h:468
HRESULT TransferData(T *pT, bool bReading, void *pData, RowClass *pRow, MapClass *, HACCESSOR hAccessor)
Definition: atldb_orig.h:19154
DBLENGTH GUID_NULL
Definition: atldb_orig.h:18720
ITypeInfo * pTypeInfo
Definition: atldb_cubrid.h:478
ULONG CalcDescripBuffers(ULONG cPropInfoSet, DBPROPINFOSET *pPropInfoSet)
#define SETBIT(word, pos)
ArrayType _RowsetArrayType
Definition: atldb_orig.h:29365
WCHAR m_szDomainName[129]
DBLENGTH DBTYPE_WSTR
Definition: atldb_orig.h:18829
int
Definition: mprec.c:252
BEGIN_COM_MAP(CSchemaRowsetImpl) COM_INTERFACE_ENTRY(IRowsetInfo) COM_INTERFACE_ENTRY(IAccessor) COM_INTERFACE_ENTRY(IObjectWithSite) COM_INTERFACE_ENTRY(IColumnsInfo) COM_INTERFACE_ENTRY(IConvertType) COM_INTERFACE_ENTRY(IRowsetIdentity) COM_INTERFACE_ENTRY(IRowset) HRESULT FinalConstruct()
const DWORD ARGCHK_PROPERTIESINERROR
Definition: atldb_orig.h:3127
void FreeDBIDs(DBID *pdbidSrc)
Definition: atldb_orig.h:2256
__if_exists(T::Fire_OnFieldChange)
Definition: atldb_orig.h:31037
HRESULT Compare(DBCOMPAREOP CompareOp, DBTYPE wType, const char *szRowValue, const char *szFindValue)
Definition: type.cpp:956
STDMETHOD() GetErrorInfo(ULONG ulRecordNum, LCID, IErrorInfo **ppErrorInfo)
CRowsetImpl< T, Storage, CreatorClass, ArrayType, RowClass, RowsetInterface > _RowsetBaseClass
Definition: atldb_orig.h:29361
CComPtr< IUnknown > spCustError
DATE m_DateCreated
DBCOLUMNFLAGS_ISFIXEDLENGTH
Definition: atldb_orig.h:18709
RowClass _HRowClass
Definition: atldb_orig.h:22942
DBPROPID dwPropId
Definition: atldb_cubrid.h:396
CreatorClass _RowsetCreatorClass
Definition: atldb_orig.h:29496
HRESULT FinalConstruct()
FAILED(hr)||varDeferred. boolVal
* pcCols
Definition: atldb_orig.h:18836
DWORD_PTR dwVal
Definition: atldb_cubrid.h:407
HRESULT GetCommandFromID(DBID *pTableID, DBID *pIndexID)
STDMETHOD() GetNextRows(HCHAPTER hReserved, DBROWOFFSET lRowsOffset, DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained, HROW **prghRows)
DBLENGTH DBTYPE_STR
Definition: atldb_orig.h:18816
WCHAR m_szCharSetCatalog[129]
#define DivDword(dw)
VARIANT vValue
Definition: atldb_cubrid.h:388
HRESULT Fire_OnFieldChange(IRowset *pRowset, HROW hRow, DBORDINAL cColumns, DBORDINAL *rgColumns, DBREASON eReason, DBEVENTPHASE ePhase, BOOL fCantDeny)
#define FALSE
Definition: dict.h:29
CAutoVectorPtr< ULONG > m_rgiPropSetDex
OUT_OF_LINE HRESULT InitUPropSetsSupported()
if(pdbidDest-> uName. pwszName) memcpy(pdbidDest -> uName. pwszName, pdbidSrc-> uName. pwszName, cwchBuffer *sizeof(WCHAR))
DBPROPOPTIONS dwOption
Definition: atldb_cubrid.h:382
const int DBPROPFLAGS_CHANGE
Definition: atldb_cubrid.h:149
return S_FALSE
Definition: atldb_orig.h:2185
name
Definition: atldb_orig.h:18709
#define PROVIDER_COLUMN_ENTRY_TYPE_PS(name, ordinal, type, precision, scale, member)
Definition: atldb_orig.h:18780
ATL_VARIANT_FALSE DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ ATL_VARIANT_FALSE DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ ATL_VARIANT_TRUE
Definition: Session.h:334
HRESULT SetCommandText(DBID *pTableID, DBID *pIndexID)
HRESULT GetNextRowsSkipDeleted(HCHAPTER, DBROWOFFSET lRowsOffset, DBROWCOUNT cRows, DBCOUNTITEM *pcRowsObtained, HROW **prghRows)
Definition: atldb_orig.h:23721
#define END_PROVIDER_COLUMN_MAP()
Definition: atldb_orig.h:18834
#define OUT_OF_LINE
Definition: atldb_orig.h:1233
WCHAR m_szTable[129]
DBCOLUMNFLAGS dwFlags
Definition: atldb_cubrid.h:482
CAtlArray< RecordClass > m_rgErrors
WCHAR m_szCatalog[129]
size
Definition: atldb_orig.h:18745
BindingVector _BindingVector
Definition: atldb_orig.h:17761
m_szTableCatalog m_szTableName m_guidColumn PROVIDER_COLUMN_ENTRY_PS("COLUMN_PROPID", 6, 10, 0xFF, m_ulColumnPropID) PROVIDER_COLUMN_ENTRY_PS("ORDINAL_POSITION"
void SetRestrictions(ULONG cRestrictions, GUID *, ULONG *rgRestrictions)
Definition: atldb_orig.h:13763
* e
Definition: mprec.c:902
ULONG m_cElemPerSupported
case DBKIND_NAME
Definition: atldb_orig.h:2041
m_szTableCatalog PROVIDER_COLUMN_ENTRY_WSTR("TABLE_SCHEMA", 2, m_szTableSchema) PROVIDER_COLUMN_ENTRY_WSTR("TABLE_NAME"
PPROPCOLID FindColumnId(const DBID *pdbidProp)
int * offset
Definition: expat.h:891
HRESULT AddColumnId(DBPROP *pProp)
ATL_VARIANT_FALSE ATL_VARIANT_FALSE
Definition: Session.h:289
LPOLESTR DBORDINAL colSize
Definition: atldb_orig.h:18671
WCHAR m_szCollationSchema[129]
WCHAR m_szTableCatalog[129]
HRESULT NameFromDBID(DBID *pDBID, CComBSTR &bstr, bool bIndex)
#define DBID_USE_GUID_OR_PGUID(e)
Definition: atldb_orig.h:1478
else return E_OUTOFMEMORY
Definition: atldb_orig.h:2027
GUID * pguidSet
NULL
Definition: atldb_orig.h:18709
#define PROVIDER_COLUMN_ENTRY_TYPE_LENGTH(name, ordinal, type, size, member)
Definition: atldb_orig.h:18757
HRESULT GetPropertySetIndex(const GUID *pPropertySet)
ULONG cPropIds
Definition: atldb_cubrid.h:421
DBCOUNTITEM KeyType
Definition: atldb_orig.h:18983
HRESULT InternalFInit(PGetPropSet pfnGetSet, CUtlPropsBase *pCopyMe=NULL)
void WINAPI AtlDumpProperty(DWORD dwPropertyID, DWORD dwStatus)
Definition: atldb_cubrid.h:276
STDMETHOD() GetCustomErrorObject(ULONG ulRecordNum, REFIID riid, IUnknown **ppObject)
case DBKIND_PGUID_PROPID
Definition: atldb_orig.h:2154
case DBKIND_PGUID_NAME
Definition: atldb_orig.h:2079
ArrayType _RowsetArrayType
Definition: atldb_orig.h:29488
#define PROVIDER_COLUMN_ENTRY_STR(name, ordinal, member)
Definition: atldb_orig.h:18808
pdbidDest uName ulPropid
Definition: atldb_orig.h:2033
VARIANT_BOOL m_bColumnHasDefault
STDMETHOD() GetBasicErrorInfo(ULONG ulRecordNum, ERRORINFO *pErrorInfo)
c
Definition: mprec.c:368
ULONG DBPROP * pDBProp
Definition: Rowset.h:133
LPOLESTR DBORDINAL BYTE BYTE scale
Definition: atldb_orig.h:18671
DATASOURCE_FLAGS
HRESULT RemoveColumnId(const DBID *pdbidProp)
HRESULT AddString(LPOLESTR szName, DBORDINAL ordinal, DBLENGTH colSize, DBBYTEOFFSET offset)
LPOLESTR DBORDINAL BYTE precision
Definition: atldb_orig.h:18671
HRESULT Fire_OnRowChange(IRowset *pRowset, DBCOUNTITEM cRows, const HROW rghRows[], DBREASON eReason, DBEVENTPHASE ePhase, BOOL fCantDeny)
virtual HRESULT OnPropertyChanged(ULONG, DBPROP *pDBProp)
Definition: atldb_orig.h:11708
CSchemaRowsetImpl< T, Storage, CreatorClass, ArrayType, RowClass, RowsetInterface > _RowsetBaseClass
Definition: atldb_orig.h:29484
HRESULT SetProperties(const DWORD, const ULONG cPropertySets, const DBPROPSET rgPropertySets [], const ULONG cSelectProps=1, const GUID *const ppGuid []=NULL, bool bIsCreating=false)
Definition: atldb_orig.h:6188
void WINAPI AtlDumpPropsetIID(REFIID iid, DWORD dwStatus)
Definition: atldb_cubrid.h:159
ERRORINFO * pInfo
case DBKIND_PROPID
Definition: atldb_orig.h:2173
CAtlMap< HROW, Storage *> m_mapCachedData
LPOLESTR szVal
Definition: atldb_cubrid.h:409
HROW HACCESSOR void * pSrcData
Definition: atldb_orig.h:31032
DISPPARAMS dispparams
#define ATLDB_NO_STRING
Definition: atldb_orig.h:107
#define LONG
Definition: curl.h:504
LPOLESTR GetErrorSource(ERRORINFO &)
STDMETHOD() GetRecordCount(ULONG *pcRecords)
cwchBuffer
Definition: atldb_orig.h:2043
WCHAR m_szColumnDefault[129]
iid
Definition: Rowset.h:87
ULONG m_ulPropID
OUT_OF_LINE HRESULT InternalFinalConstruct(IUnknown *)
Definition: atldb_orig.h:17771
WCHAR m_szDomainCatalog[129]
HRESULT Add(LPOLESTR szName, DBORDINAL ordinal, DBLENGTH colSize, DBTYPE type, BYTE precision, BYTE scale, DBBYTEOFFSET offset, DWORD flags=DBCOLUMNFLAGS_ISFIXEDLENGTH)
Definition: atldb_orig.h:18853
Storage _StorageClass
Definition: atldb_orig.h:29369
HRESULT GetPropertiesArgChk(const ULONG cPropertySets, const DBPROPIDSET rgPropertySets [], ULONG *pcProperties, DBPROPSET **prgProperties)
HRESULT ValidateCommandID(DBID *pTableID, DBID *pIndexID)
DBBYTEOFFSET cbOffset
Definition: atldb_cubrid.h:494
m_szCatalog m_szTable m_guid m_ulPropID DBTYPE_DATE
WCHAR m_szColumnName[129]
CComBSTR m_strCommandText
case DBKIND_GUID
Definition: atldb_orig.h:2177
ULONG m_ulColumnFlags
CColumnIds * pCColumnIds
Definition: atldb_cubrid.h:384
case DBKIND_GUID_PROPID
Definition: atldb_orig.h:2032
virtual HRESULT GetIndexofPropSet(const GUID *pPropSet, ULONG *pulCurSet)=0
void ClearMembers()
ULONG m_cPropSetDex
#define DBID_USE_NAME(e)
ULONG GetUPropValIndex(ULONG iCurSet, DBPROPID dwPropId)
STDMETHOD() GetRowStatus(HCHAPTER, DBCOUNTITEM cRows, const HROW rghRows [], DBPENDINGSTATUS rgPendingStatus [])
DBPROPFLAGS dwFlags
Definition: atldb_cubrid.h:402
virtual HRESULT IsValidValue(ULONG, DBPROP *pDBProp)
Definition: atldb_orig.h:5620
USHORT m_nNumericPrecision
SHORT GetValShort(ULONG iPropSet, ULONG iProp)
Definition: atldb_orig.h:11481
STDMETHOD() GetPendingRows(HCHAPTER, DBPENDINGSTATUS dwRowStatus, DBCOUNTITEM *pcPendingRows, HROW **prgPendingRows, DBPENDINGSTATUS **prgPendingStatus)
BOOL IsEmpty(ULONG iPropSet, ULONG iProp)
Definition: atldb_orig.h:11391
#define err(fd,...)
Definition: porting.h:425
HRESULT CreateRowset(IUnknown *pUnkOuter, DBID *pTableID, DBID *pIndexID, REFIID riid, ULONG cPropertySets, DBPROPSET rgPropertySets [], IUnknown **ppRowset, RowsetClass *&pRowsetObj)
short m_nNumericScale
LONG GetValLong(ULONG iPropSet, ULONG iProp)
Definition: atldb_orig.h:11516
OUT_OF_LINE HRESULT InternalCreateSchemaRowset(IUnknown *pUnkOuter, ULONG, const VARIANT [], REFIID riid, ULONG cPropertySets, DBPROPSET rgPropertySets [], IUnknown **ppRowset, IUnknown *pUnkThis, CUtlPropsBase *pProps, IUnknown *pUnkSession)
Definition: atldb_orig.h:13461
ULONG m_ulOrdinalPosition
WCHAR m_szDesc[129]
ULONG m_ulCharOctetLength
HRESULT IsUpdateAllowed(DBPENDINGSTATUS, HROW, DBROWSTATUS *)
WCHAR m_szCollationCatalog[129]
return S_OK
Definition: atldb_orig.h:2189
#define _ATLDUMPPROPERTY(dwPropertyID, dwStatus)
Definition: atldb_orig.h:327
WCHAR m_szDomainSchema[129]
DWORD GetErrorHelpContext(ERRORINFO &)
#define EXPANDGUID(guid)
m_szCatalog m_szTable m_guid m_ulPropID PROVIDER_COLUMN_ENTRY_TYPE_PS("DATE_CREATED", 8, DBTYPE_DATE, 0xFF, 0xFF, m_DateCreated) PROVIDER_COLUMN_ENTRY_TYPE_PS("DATE_MODIFIED"
GetPropValue & DBPROPSET_ROWSET
Definition: Rowset.h:83
void FreeMemory()
Definition: atldb_orig.h:9874
WCHAR m_szTableSchema[129]
UPROPSET * m_pUPropSet
CComVariant varDeferred
Definition: atldb_orig.h:31091
SchemaClass _SchemaClass
Definition: atldb_orig.h:13309
#define true
Definition: system.h:94
LPOLESTR DBORDINAL flags DBCOLUMNFLAGS_MAYBENULL
return k
Definition: mprec.c:281
WCHAR m_szSchema[129]
STDMETHOD() CreateAccessor(DBACCESSORFLAGS dwAccessorFlags, DBCOUNTITEM cBindings, const DBBINDING rgBindings[], DBLENGTH, HACCESSOR *phAccessor, DBBINDSTATUS rgStatus [])
ULONG m_cElemPerSupported
UPROPINFO ** rgpUPropInfo
Definition: atldb_cubrid.h:423
HRESULT GetPropertyInfo(ULONG cPropertySets, const DBPROPIDSET rgPropertySets [], ULONG *pcPropertyInfoSets, DBPROPINFOSET **prgPropertyInfoSets, WCHAR **ppDescBuffer, bool bInitialized=true, const GUID *pGuid=NULL)
ULONG GetCountOfPropColids()
static HRESULT SetPropertiesArgChk(const ULONG cPropertySets, const DBPROPSET rgPropertySets [])
HRESULT FInit(GUID *pguidSet=(GUID *) &GUID_NULL)
Definition: atldb_orig.h:3608
LPOLESTR OLESTR(name)
LPOLESTR DBORDINAL flags
Definition: atldb_orig.h:18671
WCHAR m_szCharSetName[129]
ATL_VARIANT_FALSE DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ ATL_VARIANT_FALSE DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPFLAGS_ROWSET DBPROPFLAGS_READ DBPROPVAL_UP_CHANGE DBPROPVAL_UP_INSERT DBPROPVAL_UP_DELETE
Definition: Session.h:338
DBLENGTH dbid
Definition: ColumnsRowset.h:67
void RemoveInternalFlags(ULONG iPropSet, ULONG iProp, DWORD dwFlags)
Definition: atldb_orig.h:11334
DBPROPOPTIONS dwOption
Definition: atldb_cubrid.h:434
DBPROPOPTIONS dwOption
Definition: atldb_cubrid.h:413
WCHAR m_szCharSetSchema[129]
UPROPVAL * pUPropVal
Definition: atldb_cubrid.h:425
STDMETHOD() Update(HCHAPTER, DBCOUNTITEM cRows, const HROW rghRows [], DBCOUNTITEM *pcRows, HROW **prgRows, DBROWSTATUS **prgRowStatus)
const ULONG cchDescBuffSize
Definition: atldb_orig.h:3118
DBROWCOUNT AbsVal(DBROWCOUNT val)
Definition: atldb_cubrid.h:126
BEGIN_PROVIDER_COLUMN_MAP(CCOLUMNSRow) PROVIDER_COLUMN_ENTRY_WSTR("TABLE_CATALOG"
#define BEGIN_PROVIDER_COLUMN_MAP(theClass)
Definition: atldb_orig.h:18594
#define PROVIDER_COLUMN_ENTRY_WSTR(name, ordinal, member)
Definition: atldb_orig.h:18821
HROW HACCESSOR hAccessor
Definition: atldb_orig.h:31029
#define DBID_USE_PROPID(e)
<< DBKIND_GUID \|1<< DBKIND_GUID_NAME \|1<< DBKIND_GUID_PROPID \|1<< DBKIND_PGUID_NAME \|1<< DBKIND_PGUID_PROPID)) #define DBID_USE_GUID(e)(1<< DBKIND_GUID \|1<< DBKIND_GUID_NAME \|1<< DBKIND_GUID_PROPID)) #define DBID_USE_PGUID(e)(1<< DBKIND_PGUID_NAME \|1<< DBKIND_PGUID_PROPID)) #define DBID_USE_NAME(e)(1<< DBKIND_NAME \|1<< DBKIND_GUID_NAME \|1<< DBKIND_PGUID_NAME)) #define DBID_USE_PROPID(e)(1<< DBKIND_PROPID \|1<< DBKIND_GUID_PROPID \|1<< DBKIND_PGUID_PROPID)) #define DBID_IS_BOOKMARK(dbid)(dbid.eKind) &&dbid. uGuid.guid==DBCOL_SPECIALCOL||DBID_USE_PGUID(dbid.eKind) &&*dbid. uGuid. pguid==DBCOL_SPECIALCOL) #define DivDword(dw) #define ModDword(dw) #define DwordSizeofBits(nBits) #define CLEARBITARRAY(rgdwFlags) template< class T > BOOL InRange(const T &val, const T &valMin, const T &valMax) { return(valMin<=val &&val<=valMax);} class CBitFieldOps { public:void SETBIT(DWORD rgdwFlags [], const DWORD dwBit) { rgdwFlags [DivDword(dwBit)]|=1<< ModDword(dwBit);} void CLEARBIT(DWORD rgdwFlags[], const DWORD dwBit) { rgdwFlags [DivDword(dwBit)] &=~(1<< ModDword(dwBit));} DWORD TESTBIT(const DWORD rgdwFlags [], const DWORD dwBit) { return(rgdwFlags [DivDword(dwBit)] &(1<< ModDword(dwBit))) !=0;} };class CDBIDOps { public:HRESULT CompareDBIDs(const DBID *pdbid1, const DBID *pdbid2) { static const BYTE s_rgbKind[]={ DBKIND_PGUID_NAME, DBKIND_PGUID_PROPID, DBKIND_NAME, DBKIND_GUID_NAME, DBKIND_GUID_PROPID, DBKIND_PROPID, DBKIND_GUID };if(!pdbid1||!pdbid2) return S_FALSE;DBKIND tmp1=0;DBKIND tmp2=(DBKIND)(sizeof(s_rgbKind)/sizeof(*s_rgbKind));if(!InRange(pdbid2-> eKind, tmp1, tmp2)) { ATLTRACE(atlTraceDBProvider, 0, _T("Column ID out of Range\"));return E_FAIL;} if(pdbid1-> eKind !=pdbid2-> eKind &&pdbid1-> eKind !=s_rgbKind [pdbid2-> eKind]) return S_FALSE;if(DBID_USE_GUID_OR_PGUID(pdbid1-> eKind)) { if(!DBID_USE_GUID_OR_PGUID(pdbid2-> eKind)) return S_FALSE;if(!InlineIsEqualGUID(DBID_USE_PGUID(pdbid1-> eKind) ? *(pdbid1-> uGuid. pguid) :pdbid1-> uGuid.guid, DBID_USE_PGUID(pdbid2-> eKind) ? *(pdbid2-> uGuid. pguid) :pdbid2-> uGuid. guid)) return S_FALSE;} if(DBID_USE_NAME(pdbid1-> eKind)) { if(!DBID_USE_NAME(pdbid2-> eKind)) return S_FALSE;if((pdbid1-> uName. pwszName==NULL) !=(pdbid2-> uName. pwszName==NULL)) return S_FALSE;if(pdbid1-> uName. pwszName &&pdbid2-> uName. pwszName) { if(wcscmp(pdbid1-> uName. pwszName, pdbid2-> uName. pwszName) !=0) return S_FALSE;} } if(DBID_USE_PROPID(pdbid1-> eKind)) { if(!DBID_USE_PROPID(pdbid2-> eKind)) return S_FALSE;if(pdbid1-> uName. ulPropid !=pdbid2-> uName. ulPropid) return S_FALSE;} return S_OK;} static HRESULT IsValidDBID(const DBID *pdbid1) { ATLASSERT(pdbid1);if(pdbid1 &&((pdbid1->eKind==DBKIND_GUID_NAME)||(pdbid1->eKind==DBKIND_GUID_PROPID)||(pdbid1->eKind==DBKIND_NAME)||(pdbid1->eKind==DBKIND_PGUID_NAME)||(pdbid1->eKind==DBKIND_PGUID_PROPID)||(pdbid1->eKind==DBKIND_PROPID)||(pdbid1->eKind==DBKIND_GUID))) return S_OK;else return S_FALSE;} HRESULT CopyDBIDs(DBID *pdbidDest, const DBID *pdbidSrc) { size_t cwchBuffer;ATLASSERT(pdbidDest||pdbidSrc);if(!pdbidDest||!pdbidSrc) return S_FALSE;pdbidDest-> eKind=pdbidSrc-> eKind;switch(pdbidSrc-> eKind) { case DBKIND_GUID_NAME:pdbidDest-> uGuid.guid=pdbidSrc-> uGuid.guid;cwchBuffer=ocslen(pdbidSrc-> uName. pwszName);cwchBuffer++;pdbidDest-> uName pwszName
Definition: atldb_orig.h:2004
DATE m_DateModified
#define TRUE
Definition: dict.h:33
CComBSTR m_strIndexText
HRESULT InternalGetDefaultValue(PGetPropSet pfnGetSet, ULONG iPropSet, DBPROPID dwPropId, DWORD *pdwOption, VARIANT *pVar)
BEGIN_PROVIDER_COLUMN_MAP(CTABLESRow) PROVIDER_COLUMN_ENTRY_WSTR("TABLE_CATALOG"
STDMETHOD() SetData(HROW hRow, HACCESSOR hAccessor, void *pSrcData)
HRESULT InternalInitUPropSetsSupported(PGetPropSet pfnGetSet)
CComAutoCriticalSection m_oCriticalSection
HRESULT Fire_OnRowsetChange(IRowset *pRowset, DBREASON eReason, DBEVENTPHASE ePhase, BOOL fCantDeny)
HRESULT FinalConstruct()
int i
Definition: dynamic_load.c:955
m_szTableCatalog m_szTableName m_guidColumn m_ulOrdinalPosition PROVIDER_COLUMN_ENTRY_TYPE_PS("COLUMN_HASDEFAULT", 8, DBTYPE_BOOL, 0xFF, 0xFF, m_bColumnHasDefault) PROVIDER_COLUMN_ENTRY_PS("COLUMN_DEFAULT"
DWORD AddRefRow()
Definition: atldb_orig.h:19013
const GUID * GetGuid(ULONG iPropSet)
Definition: atldb_orig.h:11623
LPOLESTR DBORDINAL dbtype
Definition: atldb_orig.h:18671
#define ModDword(dw)
HRESULT GetValue(size_t iColId, DWORD *pdwOptions, DBID *pColid, VARIANT *pvValue)
LPOLESTR GetErrorDescriptionString(ERRORINFO &)
ArrayType m_rgRowData
WCHAR m_szCollationName[129]
XML_ParsingStatus * status
Definition: expat.h:785
DBROWOFFSET m_iRowset
CAutoVectorPtr< DWORD > m_rgdwSupported
m_szTableCatalog m_szTableName m_guidColumn m_ulOrdinalPosition m_szColumnDefault DBTYPE_BOOL
DBTYPE_BOOL
Definition: ColumnsRowset.h:77
#define DBID_USE_PGUID(e)
ULONG m_ulDateTimePrecision
STDMETHOD() GetErrorParameters(ULONG ulRecordNum, DISPPARAMS *pdispparams)
USHORT m_nDataType
WCHAR m_szTableName[129]
static ATLCOLUMNINFO * GetColumnInfo(T *pv, DBORDINAL *pcCols)
STDMETHOD() GetOriginalData(HROW hRow, HACCESSOR hAccessor, void *pData)
const DWORD DBINTERNFLAGS_CHANGED
Definition: atldb_orig.h:3122
HRESULT InitAvailUPropSets(ULONG *pcUPropSet, UPROPSET **ppUPropSet, ULONG *pcElemPerSupported, GUID *pguid)
DBCOUNTITEM cBindings
Definition: atldb_cubrid.h:466
VARIANT * GetVariant(ULONG iPropSet, ULONG iProp)
Definition: atldb_orig.h:11341
VARIANT_BOOL m_bIsNullable
BindType _BindType
Definition: atldb_orig.h:17757
int LoadDescription(ULONG ids, PWSTR pwszBuff, ULONG cchBuff)
HRESULT GetProperties(const ULONG cPropertySets, const DBPROPIDSET rgPropertySets [], ULONG *pcProperties, DBPROPSET **prgProperties, const ULONG cSelectProps=1, const GUID *const ppGuid[]=NULL)
ULONG m_ulCharMaxLength
PROPCOLID * PPROPCOLID
Definition: atldb_cubrid.h:441
void SendColumnSetFailureNotification(T *pT, HROW hNotifyRow, T::_BindType *pBinding, CAtlArray< DBORDINAL > &rgColumns)
Definition: atldb_orig.h:19070
void SendRowsFirstChangeFailureNotification(T *pT, RowClass *pRow, HROW *phNotifyRow, bool bDeferred)
Definition: atldb_orig.h:19105
if(!pT-> m_rgRowHandles. Lookup(hRow, pRow)) return DB_E_BADROWHANDLE
#define CLEARBIT(word, pos)
OUT_OF_LINE HRESULT FInit(CUtlPropsBase *pCopyMe=NULL)
#define PROVIDER_COLUMN_ENTRY_PS(name, ordinal, precision, scale, member)
Definition: atldb_orig.h:18724
PPROPCOLID AddNode()
Definition: atldb_orig.h:2814
CreatorClass _RowsetCreatorClass
Definition: atldb_orig.h:29373
return _rgColumns
Definition: atldb_orig.h:18842
void FinalRelease()
virtual HRESULT InitUPropSetsSupported()=0
virtual HRESULT GetDefaultValue(ULONG iPropSet, DBPROPID dwPropId, DWORD *pdwOption, VARIANT *pVar)=0
STDMETHOD() AddErrorRecord(ERRORINFO *pErrorInfo, DWORD dwLookupID, DISPPARAMS *pdispparams, IUnknown *punkCustomError, DWORD)